• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2015-2018 Khronos Group. This work is licensed under a
2// Creative Commons Attribution 4.0 International License; see
3// http://creativecommons.org/licenses/by/4.0/
4
5[[synchronization]]
6= Synchronization and Cache Control
7
8Synchronization of access to resources is primarily the responsibility of
9the application in Vulkan.
10The order of execution of commands with respect to the host and other
11commands on the device has few implicit guarantees, and needs to be
12explicitly specified.
13Memory caches and other optimizations are also explicitly managed, requiring
14that the flow of data through the system is largely under application
15control.
16
17Whilst some implicit guarantees exist between commands, five explicit
18synchronization mechanisms are exposed by Vulkan:
19
20<<synchronization-fences,Fences>>::
21    Fences can: be used to communicate to the host that execution of some
22    task on the device has completed.
23
24<<synchronization-semaphores,Semaphores>>::
25    Semaphores can: be used to control resource access across multiple
26    queues.
27
28<<synchronization-events,Events>>::
29    Events provide a fine-grained synchronization primitive which can: be
30    signaled either within a command buffer or by the host, and can: be
31    waited upon within a command buffer or queried on the host.
32
33<<synchronization-pipeline-barriers,Pipeline Barriers>>::
34    Pipeline barriers also provide synchronization control within a command
35    buffer, but at a single point, rather than with separate signal and wait
36    operations.
37
38<<renderpass,Render Passes>>::
39    Render passes provide a useful synchronization framework for most
40    rendering tasks, built upon the concepts in this chapter.
41    Many cases that would otherwise need an application to use other
42    synchronization primitives can: be expressed more efficiently as part of
43    a render pass.
44
45
46[[synchronization-dependencies]]
47== Execution and Memory Dependencies
48
49An _operation_ is an arbitrary amount of work to be executed on the host, a
50device, or an external entity such as a presentation engine.
51Synchronization commands introduce explicit _execution dependencies_, and
52_memory dependencies_ between two sets of operations defined by the
53command's two _synchronization scopes_.
54
55[[synchronization-dependencies-scopes]]
56The synchronization scopes define which other operations a synchronization
57command is able to create execution dependencies with.
58Any type of operation that is not in a synchronization command's
59synchronization scopes will not be included in the resulting dependency.
60For example, for many synchronization commands, the synchronization scopes
61can: be limited to just operations executing in specific
62<<synchronization-pipeline-stages,pipeline stages>>, which allows other
63pipeline stages to be excluded from a dependency.
64Other scoping options are possible, depending on the particular command.
65
66[[synchronization-dependencies-execution]]
67An _execution dependency_ is a guarantee that for two sets of operations,
68the first set must: _happen-before_ the second set.
69If an operation happens-before another operation, then the first operation
70must: complete before the second operation is initiated.
71More precisely:
72
73  * Let *A* and *B* be separate sets of operations.
74  * Let *S* be a synchronization command.
75  * Let *A~S~* and *B~S~* be the synchronization scopes of *S*.
76  * Let *A'* be the intersection of sets *A* and *A~S~*.
77  * Let *B'* be the intersection of sets *B* and *B~S~*.
78  * Submitting *A*, *S* and *B* for execution, in that order, will result in
79    execution dependency *E* between *A'* and *B'*.
80  * Execution dependency *E* guarantees that *A'* happens-before *B'*.
81
82[[synchronization-dependencies-chains]]
83An _execution dependency chain_ is a sequence of execution dependencies that
84form a happens-before relation between the first dependency's *A'* and the
85final dependency's *B'*.
86For each consecutive pair of execution dependencies, a chain exists if the
87intersection of *B~S~* in the first dependency and *A~S~* in the second
88dependency is not an empty set.
89The formation of a single execution dependency from an execution dependency
90chain can be described by substituting the following in the description of
91execution dependencies:
92
93  * Let *S* be a set of synchronization commands that generate an execution
94    dependency chain.
95  * Let *A~S~* be the first synchronization scope of the first command in
96    *S*.
97  * Let *B~S~* be the second synchronization scope of the last command in
98    *S*.
99
100[NOTE]
101.Note
102====
103An execution dependency is inherently also multiple execution dependencies -
104a dependency exists between each subset of *A'* and each subset of *B'*, and
105the same is true for execution dependency chains.
106For example, a synchronization command with multiple
107<<synchronization-pipeline-stages,pipeline stages>> in its stage masks
108effectively generates one dependency between each source stage and each
109destination stage.
110This can be useful to think about when considering how execution chains are
111formed if they do not involve all parts of a synchronization command's
112dependency.
113Similarly, any set of adjacent dependencies in an execution dependency chain
114can: be considered an execution dependency chain in its own right.
115====
116
117Execution dependencies alone are not sufficient to guarantee that values
118resulting from writes in one set of operations can: be read from another set
119of operations.
120
121[[synchronization-dependencies-available-and-visible]]
122Two additional types of operation are used to control memory access.
123_Availability operations_ cause the values generated by specified memory
124write accesses to become _available_ for future access.
125Any available value remains available until a subsequent write to the same
126memory location occurs (whether it is made available or not) or the memory
127is freed.
128_Visibility operations_ cause any available values to become _visible_ to
129specified memory accesses.
130
131[[synchronization-dependencies-memory]]
132A _memory dependency_ is an execution dependency which includes availability
133and visibility operations such that:
134
135  * The first set of operations happens-before the availability operation.
136  * The availability operation happens-before the visibility operation.
137  * The visibility operation happens-before the second set of operations.
138
139Once written values are made visible to a particular type of memory access,
140they can: be read or written by that type of memory access.
141Most synchronization commands in Vulkan define a memory dependency.
142
143[[synchronization-dependencies-access-scopes]]
144The specific memory accesses that are made available and visible are defined
145by the _access scopes_ of a memory dependency.
146Any type of access that is in a memory dependency's first access scope and
147occurs in *A'* is made available.
148Any type of access that is in a memory dependency's second access scope and
149occurs in *B'* has any available writes made visible to it.
150Any type of operation that is not in a synchronization command's access
151scopes will not be included in the resulting dependency.
152
153A memory dependency enforces availability and visibility of memory accesses
154and execution order between two sets of operations.
155Adding to the description of <<synchronization-dependencies-chains,
156execution dependency chains>>:
157
158  * Let *a* be the set of memory accesses performed by *A'*.
159  * Let *b* be the set of memory accesses performed by *B'*.
160  * Let *a~S~* be the first access scope of the first command in *S*.
161  * Let *b~S~* be the second access scope of the last command in *S*.
162  * Let *a'* be the intersection of sets *a* and *a~S~*.
163  * Let *b'* be the intersection of sets *b* and *b~S~*.
164  * Submitting *A*, *S* and *B* for execution, in that order, will result in
165    a memory dependency *m* between *A'* and *B'*.
166  * Memory dependency *m* guarantees that:
167  ** Memory writes in *a'* are made available.
168  ** Available memory writes, including those from *a'*, are made visible to
169     *b'*.
170
171[NOTE]
172.Note
173====
174Execution and memory dependencies are used to solve data hazards, i.e. to
175ensure that read and write operations occur in a well-defined order.
176Write-after-read hazards can be solved with just an execution dependency,
177but read-after-write and write-after-write hazards need appropriate memory
178dependencies to be included between them.
179If an application does not include dependencies to solve these hazards, the
180results and execution orders of memory accesses are undefined.
181====
182
183
184[[synchronization-image-layout-transitions]]
185=== Image Layout Transitions
186
187Image subresources can: be transitioned from one <<resources-image-layouts,
188layout>> to another as part of a <<synchronization-dependencies-memory,
189memory dependency>> (e.g. by using an
190<<synchronization-image-memory-barriers,image memory barrier>>).
191When a layout transition is specified in a memory dependency, it
192happens-after the availability operations in the memory dependency, and
193happens-before the visibility operations.
194Image layout transitions may: perform read and write accesses on all memory
195bound to the image subresource range, so applications must: ensure that all
196memory writes have been made
197<<synchronization-dependencies-available-and-visible, available>> before a
198layout transition is executed.
199Available memory is automatically made visible to a layout transition, and
200writes performed by a layout transition are automatically made available.
201
202Layout transitions always apply to a particular image subresource range, and
203specify both an old layout and new layout.
204If the old layout does not match the new layout, a transition occurs.
205The old layout must: match the current layout of the image subresource
206range, with one exception.
207The old layout can: always be specified as ename:VK_IMAGE_LAYOUT_UNDEFINED,
208though doing so invalidates the contents of the image subresource range.
209
210ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
211As image layout transitions may: perform read and write accesses on the
212memory bound to the image, if the image subresource affected by the layout
213transition is bound to peer memory for any device in the current device mask
214then the memory heap the bound memory comes from must: support the
215ename:VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT and
216ename:VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT capabilities as returned by
217flink:vkGetDeviceGroupPeerMemoryFeatures.
218endif::VK_VERSION_1_1,VK_KHR_device_group[]
219
220[NOTE]
221.Note
222====
223Setting the old layout to ename:VK_IMAGE_LAYOUT_UNDEFINED implies that the
224contents of the image subresource need not be preserved.
225Implementations may: use this information to avoid performing expensive data
226transition operations.
227====
228
229[NOTE]
230.Note
231====
232Applications must: ensure that layout transitions happen-after all
233operations accessing the image with the old layout, and happen-before any
234operations that will access the image with the new layout.
235Layout transitions are potentially read/write operations, so not defining
236appropriate memory dependencies to guarantee this will result in a data
237race.
238====
239
240Image layout transitions interact with <<resources-memory-aliasing,memory
241aliasing>>.
242
243
244[[synchronization-pipeline-stages]]
245=== Pipeline Stages
246
247The work performed by an <<fundamentals-queueoperation-command-types, action
248or synchronization command>> consists of multiple operations, which are
249performed as a sequence of logically independent steps known as _pipeline
250stages_.
251The exact pipeline stages executed depend on the particular command that is
252used, and current command buffer state when the command was recorded.
253<<drawing,Drawing commands>>, <<dispatch,dispatching commands>>,
254<<copies,copy commands>>, <<clears,clear commands>>, and <<synchronization,
255synchronization commands>> all execute in different sets of
256<<synchronization-pipeline-stages-types,pipeline stages>>.
257<<synchronization, Synchronization commands>> do not execute in a defined
258pipeline, but do execute ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT and
259ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT.
260
261[NOTE]
262.Note
263====
264Operations performed by synchronization commands (e.g.
265<<synchronization-dependencies-available-and-visible, availability and
266visibility operations>>) are not executed by a defined pipeline stage.
267However other commands can still synchronize with them via the
268ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT and
269ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT pipeline stages.
270====
271
272Execution of operations across pipeline stages must: adhere to
273<<synchronization-implicit, implicit ordering guarantees>>, particularly
274including <<synchronization-pipeline-stages-order, pipeline stage order>>.
275Otherwise, execution across pipeline stages may: overlap or execute out of
276order with regards to other stages, unless otherwise enforced by an
277execution dependency.
278
279[open,refpage='VkPipelineStageFlagBits',desc='Bitmask specifying pipeline stages',type='enums']
280--
281
282Several of the synchronization commands include pipeline stage parameters,
283restricting the <<synchronization-dependencies-scopes, synchronization
284scopes>> for that command to just those stages.
285This allows fine grained control over the exact execution dependencies and
286accesses performed by action commands.
287Implementations should: use these pipeline stages to avoid unnecessary
288stalls or cache flushing.
289
290Bits which can be set, specifying pipeline stages, are:
291
292include::../api/enums/VkPipelineStageFlagBits.txt[]
293
294  * ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT specifies the stage of the
295    pipeline where any commands are initially received by the queue.
296  * ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT specifies the stage of the
297    pipeline where Draw/DispatchIndirect data structures are consumed.
298ifdef::VK_NVX_device_generated_commands[]
299    This stage also includes reading commands written by
300    flink:vkCmdProcessCommandsNVX.
301endif::VK_NVX_device_generated_commands[]
302  * ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT specifies the stage of the
303    pipeline where vertex and index buffers are consumed.
304  * ename:VK_PIPELINE_STAGE_VERTEX_SHADER_BIT specifies the vertex shader
305    stage.
306  * ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT specifies the
307    tessellation control shader stage.
308  * ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT specifies the
309    tessellation evaluation shader stage.
310  * ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT specifies the geometry
311    shader stage.
312  * ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT specifies the fragment
313    shader stage.
314  * ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT specifies the stage of
315    the pipeline where early fragment tests (depth and stencil tests before
316    fragment shading) are performed.
317    This stage also includes <<renderpass-load-store-ops, subpass load
318    operations>> for framebuffer attachments with a depth/stencil format.
319  * ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT specifies the stage of
320    the pipeline where late fragment tests (depth and stencil tests after
321    fragment shading) are performed.
322    This stage also includes <<renderpass-load-store-ops, subpass store
323    operations>> for framebuffer attachments with a depth/stencil format.
324  * ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT specifies the stage
325    of the pipeline after blending where the final color values are output
326    from the pipeline.
327    This stage also includes <<renderpass-load-store-ops, subpass load and
328    store operations>> and multisample resolve operations for framebuffer
329    attachments with a color format.
330  * ename:VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT specifies the execution of a
331    compute shader.
332  * [[synchronization-pipeline-stages-transfer]]
333    ename:VK_PIPELINE_STAGE_TRANSFER_BIT specifies the execution of copy
334    commands.
335    This includes the operations resulting from all <<copies,copy
336    commands>>, <<clears,clear commands>> (with the exception of
337    flink:vkCmdClearAttachments), and flink:vkCmdCopyQueryPoolResults.
338  * ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT specifies the final stage in
339    the pipeline where operations generated by all commands complete
340    execution.
341  * ename:VK_PIPELINE_STAGE_HOST_BIT specifies a pseudo-stage indicating
342    execution on the host of reads/writes of device memory.
343    This stage is not invoked by any commands recorded in a command buffer.
344  * ename:VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT specifies the execution of all
345    graphics pipeline stages, and is equivalent to the logical OR of:
346  ** ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
347  ** ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
348  ** ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
349  ** ename:VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
350  ** ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
351  ** ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
352  ** ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
353  ** ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
354  ** ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
355  ** ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
356  ** ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
357  ** ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
358ifdef::VK_EXT_conditional_rendering[]
359  ** ename:VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT
360endif::VK_EXT_conditional_rendering[]
361  * ename:VK_PIPELINE_STAGE_ALL_COMMANDS_BIT is equivalent to the logical OR
362    of every other pipeline stage flag that is supported on the queue it is
363    used with.
364ifdef::VK_EXT_conditional_rendering[]
365  * ename:VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT specifies the
366    stage of the pipeline where the predicate of conditional rendering is
367    consumed.
368endif::VK_EXT_conditional_rendering[]
369ifdef::VK_NVX_device_generated_commands[]
370  * ename:VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX specifies the stage of
371    the pipeline where device-side generation of commands via
372    flink:vkCmdProcessCommandsNVX is handled.
373endif::VK_NVX_device_generated_commands[]
374
375[NOTE]
376.Note
377====
378An execution dependency with only ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
379in the destination stage mask will only prevent that stage from executing in
380subsequently submitted commands.
381As this stage does not perform any actual execution, this is not observable
382- in effect, it does not delay processing of subsequent commands.
383Similarly an execution dependency with only
384ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT in the source stage mask will
385effectively not wait for any prior commands to complete.
386
387When defining a memory dependency, using only
388ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT or
389ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT would never make any accesses
390available and/or visible because these stages do not access memory.
391
392ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT and
393ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT are useful for accomplishing layout
394transitions and queue ownership operations when the required execution
395dependency is satisfied by other means - for example, semaphore operations
396between queues.
397====
398
399--
400
401[open,refpage='VkPipelineStageFlags',desc='Bitmask of VkPipelineStageFlagBits',type='enums']
402--
403include::../api/flags/VkPipelineStageFlags.txt[]
404
405sname:VkPipelineStageFlags is a bitmask type for setting a mask of zero or
406more slink:VkPipelineStageFlagBits.
407--
408
409[[synchronization-pipeline-stages-masks]]
410If a synchronization command includes a source stage mask, its first
411<<synchronization-dependencies-scopes, synchronization scope>> only includes
412execution of the pipeline stages specified in that mask, and its first
413<<synchronization-dependencies-access-scopes, access scope>> only includes
414memory access performed by pipeline stages specified in that mask.
415If a synchronization command includes a destination stage mask, its second
416<<synchronization-dependencies-scopes, synchronization scope>> only includes
417execution of the pipeline stages specified in that mask, and its second
418<<synchronization-dependencies-access-scopes, access scope>> only includes
419memory access performed by pipeline stages specified in that mask.
420
421[NOTE]
422.Note
423====
424Including a particular pipeline stage in the first
425<<synchronization-dependencies-scopes, synchronization scope>> of a command
426implicitly includes <<synchronization-pipeline-stages-order, logically
427earlier>> pipeline stages in the synchronization scope.
428Similarly, the second <<synchronization-dependencies-scopes, synchronization
429scope>> includes <<synchronization-pipeline-stages-order, logically later>>
430pipeline stages.
431
432However, note that <<synchronization-dependencies-access-scopes, access
433scopes>> are not affected in this way - only the precise stages specified
434are considered part of each access scope.
435====
436
437Certain pipeline stages are only available on queues that support a
438particular set of operations.
439The following table lists, for each pipeline stage flag, which queue
440capability flag must: be supported by the queue.
441When multiple flags are enumerated in the second column of the table, it
442means that the pipeline stage is supported on the queue if it supports any
443of the listed capability flags.
444For further details on queue capabilities see
445<<devsandqueues-physical-device-enumeration,Physical Device Enumeration>>
446and <<devsandqueues-queues,Queues>>.
447
448[[synchronization-pipeline-stages-supported]]
449.Supported pipeline stage flags
450[cols="60%,40%",options="header"]
451|====
452|Pipeline stage flag                                          | Required queue capability flag
453|ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT                      | None required
454|ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT                    | ename:VK_QUEUE_GRAPHICS_BIT or ename:VK_QUEUE_COMPUTE_BIT
455|ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT                     | ename:VK_QUEUE_GRAPHICS_BIT
456|ename:VK_PIPELINE_STAGE_VERTEX_SHADER_BIT                    | ename:VK_QUEUE_GRAPHICS_BIT
457|ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT      | ename:VK_QUEUE_GRAPHICS_BIT
458|ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT   | ename:VK_QUEUE_GRAPHICS_BIT
459|ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT                  | ename:VK_QUEUE_GRAPHICS_BIT
460|ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT                  | ename:VK_QUEUE_GRAPHICS_BIT
461|ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT             | ename:VK_QUEUE_GRAPHICS_BIT
462|ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT              | ename:VK_QUEUE_GRAPHICS_BIT
463|ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT          | ename:VK_QUEUE_GRAPHICS_BIT
464|ename:VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT                   | ename:VK_QUEUE_COMPUTE_BIT
465|ename:VK_PIPELINE_STAGE_TRANSFER_BIT                         | ename:VK_QUEUE_GRAPHICS_BIT, ename:VK_QUEUE_COMPUTE_BIT or ename:VK_QUEUE_TRANSFER_BIT
466|ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT                   | None required
467|ename:VK_PIPELINE_STAGE_HOST_BIT                             | None required
468|ename:VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT                     | ename:VK_QUEUE_GRAPHICS_BIT
469|ename:VK_PIPELINE_STAGE_ALL_COMMANDS_BIT                     | None required
470ifdef::VK_EXT_conditional_rendering[]
471|ename:VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT        | ename:VK_QUEUE_GRAPHICS_BIT or ename:VK_QUEUE_COMPUTE_BIT
472endif::VK_EXT_conditional_rendering[]
473ifdef::VK_NVX_device_generated_commands[]
474|ename:VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX              | ename:VK_QUEUE_GRAPHICS_BIT or ename:VK_QUEUE_COMPUTE_BIT
475endif::VK_NVX_device_generated_commands[]
476|====
477
478[[synchronization-pipeline-stages-order]]
479Pipeline stages that execute as a result of a command logically complete
480execution in a specific order, such that completion of a logically later
481pipeline stage must: not happen-before completion of a logically earlier
482stage.
483This means that including any stage in the source stage mask for a
484particular synchronization command also implies that any logically earlier
485stages are included in *A~S~* for that command.
486
487Similarly, initiation of a logically earlier pipeline stage must: not
488happen-after initiation of a logically later pipeline stage.
489Including any given stage in the destination stage mask for a particular
490synchronization command also implies that any logically later stages are
491included in *B~S~* for that command.
492
493[NOTE]
494.Note
495====
496Implementations may: not support synchronization at every pipeline stage for
497every synchronization operation.
498If a pipeline stage that an implementation does not support synchronization
499for appears in a source stage mask, it may: substitute any logically later
500stage in its place for the first synchronization scope.
501If a pipeline stage that an implementation does not support synchronization
502for appears in a destination stage mask, it may: substitute any logically
503earlier stage in its place for the second synchronization scope.
504
505For example, if an implementation is unable to signal an event immediately
506after vertex shader execution is complete, it may: instead signal the event
507after color attachment output has completed.
508
509If an implementation makes such a substitution, it must: not affect the
510semantics of execution or memory dependencies or image and buffer memory
511barriers.
512====
513
514[[synchronization-pipeline-stages-types]]
515The order and set of pipeline stages executed by a given command is
516determined by the command's pipeline type, as described below:
517
518For the graphics pipeline, the following stages occur in this order:
519
520  * ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
521  * ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
522  * ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
523  * ename:VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
524  * ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
525  * ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
526  * ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
527  * ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
528  * ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
529  * ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
530  * ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
531  * ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
532
533For the compute pipeline, the following stages occur in this order:
534
535  * ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
536  * ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
537  * ename:VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
538  * ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
539
540ifdef::VK_EXT_conditional_rendering[]
541The conditional rendering stage is formally part of both the graphics, and
542the compute pipeline.
543The pipeline stage where the predicate read happens has unspecified order
544relative to other stages of these pipelines:
545
546  * ename:VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT
547endif::VK_EXT_conditional_rendering[]
548
549For the transfer pipeline, the following stages occur in this order:
550
551  * ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
552  * ename:VK_PIPELINE_STAGE_TRANSFER_BIT
553  * ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
554
555For host operations, only one pipeline stage occurs, so no order is
556guaranteed:
557
558  * ename:VK_PIPELINE_STAGE_HOST_BIT
559
560ifdef::VK_NVX_device_generated_commands[]
561For the command processing pipeline, the following stages occur in this
562order:
563
564  * ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
565  * ename:VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX
566  * ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
567endif::VK_NVX_device_generated_commands[]
568
569
570[[synchronization-access-types]]
571=== Access Types
572
573[open,refpage='VkAccessFlagBits',desc='Bitmask specifying memory access types that will participate in a memory dependency',type='enums']
574--
575
576Memory in Vulkan can: be accessed from within shader invocations and via
577some fixed-function stages of the pipeline.
578The _access type_ is a function of the <<descriptorsets, descriptor type>>
579used, or how a fixed-function stage accesses memory.
580Each access type corresponds to a bit flag in slink:VkAccessFlagBits.
581
582[[synchronization-access-masks]]
583Some synchronization commands take sets of access types as parameters to
584define the <<synchronization-dependencies-access-scopes, access scopes>> of
585a memory dependency.
586If a synchronization command includes a source access mask, its first
587<<synchronization-dependencies-access-scopes, access scope>> only includes
588accesses via the access types specified in that mask.
589Similarly, if a synchronization command includes a destination access mask,
590its second <<synchronization-dependencies-access-scopes, access scope>> only
591includes accesses via the access types specified in that mask.
592
593Access types that can: be set in an access mask include:
594
595include::../api/enums/VkAccessFlagBits.txt[]
596
597  * ename:VK_ACCESS_INDIRECT_COMMAND_READ_BIT specifies read access to an
598    indirect command structure read as part of an indirect drawing or
599    dispatch command.
600  * ename:VK_ACCESS_INDEX_READ_BIT specifies read access to an index buffer
601    as part of an indexed drawing command, bound by
602    flink:vkCmdBindIndexBuffer.
603  * ename:VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT specifies read access to a
604    vertex buffer as part of a drawing command, bound by
605    flink:vkCmdBindVertexBuffers.
606  * ename:VK_ACCESS_UNIFORM_READ_BIT specifies read access to a
607    <<descriptorsets-uniformbuffer, uniform buffer>>.
608  * ename:VK_ACCESS_INPUT_ATTACHMENT_READ_BIT specifies read access to an
609    <<renderpass, input attachment>> within a render pass during fragment
610    shading.
611  * ename:VK_ACCESS_SHADER_READ_BIT specifies read access to a
612    <<descriptorsets-storagebuffer, storage buffer>>,
613    <<descriptorsets-uniformtexelbuffer, uniform texel buffer>>,
614    <<descriptorsets-storagetexelbuffer, storage texel buffer>>,
615    <<descriptorsets-sampledimage, sampled image>>, or
616    <<descriptorsets-storageimage, storage image>>.
617  * ename:VK_ACCESS_SHADER_WRITE_BIT specifies write access to a
618    <<descriptorsets-storagebuffer, storage buffer>>,
619    <<descriptorsets-storagetexelbuffer, storage texel buffer>>, or
620    <<descriptorsets-storageimage, storage image>>.
621  * ename:VK_ACCESS_COLOR_ATTACHMENT_READ_BIT specifies read access to a
622    <<renderpass, color attachment>>, such as via <<framebuffer-blending,
623    blending>>, <<framebuffer-logicop, logic operations>>, or via certain
624    <<renderpass-load-store-ops, subpass load operations>>.
625ifdef::VK_EXT_blend_operation_advanced[]
626    It does not include <<framebuffer-blend-advanced,advanced blend
627    operations>>.
628endif::VK_EXT_blend_operation_advanced[]
629  * ename:VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT specifies write access to a
630    <<renderpass, color or resolve attachment>> during a <<renderpass,
631    render pass>> or via certain <<renderpass-load-store-ops, subpass load
632    and store operations>>.
633  * ename:VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT specifies read access
634    to a <<renderpass, depth/stencil attachment>>, via <<fragops-ds-state,
635    depth or stencil operations>> or via certain
636    <<renderpass-load-store-ops, subpass load operations>>.
637  * ename:VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT specifies write
638    access to a <<renderpass, depth/stencil attachment>>, via
639    <<fragops-ds-state, depth or stencil operations>> or via certain
640    <<renderpass-load-store-ops, subpass load and store operations>>.
641  * ename:VK_ACCESS_TRANSFER_READ_BIT specifies read access to an image or
642    buffer in a <<copies, copy>> operation.
643  * ename:VK_ACCESS_TRANSFER_WRITE_BIT specifies write access to an image or
644    buffer in a <<clears, clear>> or <<copies, copy>> operation.
645  * ename:VK_ACCESS_HOST_READ_BIT specifies read access by a host operation.
646    Accesses of this type are not performed through a resource, but directly
647    on memory.
648  * ename:VK_ACCESS_HOST_WRITE_BIT specifies write access by a host
649    operation.
650    Accesses of this type are not performed through a resource, but directly
651    on memory.
652  * ename:VK_ACCESS_MEMORY_READ_BIT specifies read access via non-specific
653    entities.
654    These entities include the Vulkan device and host, but may: also include
655    entities external to the Vulkan device or otherwise not part of the core
656    Vulkan pipeline.
657    When included in a destination access mask, makes all available writes
658    visible to all future read accesses on entities known to the Vulkan
659    device.
660  * ename:VK_ACCESS_MEMORY_WRITE_BIT specifies write access via non-specific
661    entities.
662    These entities include the Vulkan device and host, but may: also include
663    entities external to the Vulkan device or otherwise not part of the core
664    Vulkan pipeline.
665    When included in a source access mask, all writes that are performed by
666    entities known to the Vulkan device are made available.
667    When included in a destination access mask, makes all available writes
668    visible to all future write accesses on entities known to the Vulkan
669    device.
670ifdef::VK_EXT_conditional_rendering[]
671  * ename:VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT specifies read access
672    to a predicate as part of conditional rendering.
673endif::VK_EXT_conditional_rendering[]
674ifdef::VK_NVX_device_generated_commands[]
675  * ename:VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX specifies reads from
676    sname:VkBuffer inputs to flink:vkCmdProcessCommandsNVX.
677  * ename:VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX specifies writes to the
678    target command buffer in flink:vkCmdProcessCommandsNVX.
679endif::VK_NVX_device_generated_commands[]
680ifdef::VK_EXT_blend_operation_advanced[]
681  * ename:VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT is similar to
682    ename:VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, but also includes
683    <<framebuffer-blend-advanced,advanced blend operations>>.
684endif::VK_EXT_blend_operation_advanced[]
685
686Certain access types are only performed by a subset of pipeline stages.
687Any synchronization command that takes both stage masks and access masks
688uses both to define the <<synchronization-dependencies-access-scopes, access
689scopes>> - only the specified access types performed by the specified stages
690are included in the access scope.
691An application must: not specify an access flag in a synchronization command
692if it does not include a pipeline stage in the corresponding stage mask that
693is able to perform accesses of that type.
694The following table lists, for each access flag, which pipeline stages can:
695perform that type of access.
696
697[[synchronization-access-types-supported]]
698.Supported access types
699[cols="50,50",options="header"]
700|====
701|Access flag                                                  | Supported pipeline stages
702|ename:VK_ACCESS_INDIRECT_COMMAND_READ_BIT                    | ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
703|ename:VK_ACCESS_INDEX_READ_BIT                               | ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
704|ename:VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT                    | ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
705|ename:VK_ACCESS_UNIFORM_READ_BIT                             | ename:VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, or ename:VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
706|ename:VK_ACCESS_INPUT_ATTACHMENT_READ_BIT                    | ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
707|ename:VK_ACCESS_SHADER_READ_BIT                              | ename:VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, or ename:VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
708|ename:VK_ACCESS_SHADER_WRITE_BIT                             | ename:VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, or ename:VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
709|ename:VK_ACCESS_COLOR_ATTACHMENT_READ_BIT                    | ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
710|ename:VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT                   | ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
711|ename:VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT            | ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, or ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
712|ename:VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT           | ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, or ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
713|ename:VK_ACCESS_TRANSFER_READ_BIT                            | ename:VK_PIPELINE_STAGE_TRANSFER_BIT
714|ename:VK_ACCESS_TRANSFER_WRITE_BIT                           | ename:VK_PIPELINE_STAGE_TRANSFER_BIT
715|ename:VK_ACCESS_HOST_READ_BIT                                | ename:VK_PIPELINE_STAGE_HOST_BIT
716|ename:VK_ACCESS_HOST_WRITE_BIT                               | ename:VK_PIPELINE_STAGE_HOST_BIT
717|ename:VK_ACCESS_MEMORY_READ_BIT                              | N/A
718|ename:VK_ACCESS_MEMORY_WRITE_BIT                             | N/A
719ifdef::VK_EXT_blend_operation_advanced[]
720|ename:VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT    | ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
721endif::VK_EXT_blend_operation_advanced[]
722ifdef::VK_NVX_device_generated_commands[]
723|ename:VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX                 | ename:VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX
724|ename:VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX                | ename:VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX
725endif::VK_NVX_device_generated_commands[]
726ifdef::VK_EXT_conditional_rendering[]
727|ename:VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT           | ename:VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT
728endif::VK_EXT_conditional_rendering[]
729|====
730
731[[synchronization-host-access-types]]
732If a memory object does not have the
733ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT property, then
734flink:vkFlushMappedMemoryRanges must: be called in order to guarantee that
735writes to the memory object from the host are made visible to the
736ename:VK_ACCESS_HOST_WRITE_BIT <<synchronization-access-types, access
737type>>, where it can: be further made available to the device by
738<<synchronization, synchronization commands>>.
739Similarly, flink:vkInvalidateMappedMemoryRanges must: be called to guarantee
740that writes which are visible to the ename:VK_ACCESS_HOST_READ_BIT
741<<synchronization-access-types, access type>> are made visible to host
742operations.
743
744If the memory object does have the
745ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT property flag, writes to the
746memory object from the host are automatically made visible to the
747ename:VK_ACCESS_HOST_WRITE_BIT <<synchronization-access-types,access type>>.
748Similarly, writes made visible to the ename:VK_ACCESS_HOST_READ_BIT
749<<synchronization-access-types, access type>> are automatically made visible
750to the host.
751
752[NOTE]
753.Note
754====
755The flink:vkQueueSubmit command <<synchronization-submission-host-writes,
756automatically guarantees that host writes flushed to
757ename:VK_ACCESS_HOST_WRITE_BIT are made available>> if they were flushed
758before the command executed, so in most cases an explicit memory barrier is
759not needed for this case.
760In the few circumstances where a submit does not occur between the host
761write and the device read access, writes can: be made available by using an
762explicit memory barrier.
763====
764
765--
766
767[open,refpage='VkAccessFlags',desc='Bitmask of VkAccessFlagBits',type='enums']
768--
769include::../api/flags/VkAccessFlags.txt[]
770
771sname:VkAccessFlags is a bitmask type for setting a mask of zero or more
772slink:VkAccessFlagBits.
773--
774
775
776[[synchronization-framebuffer-regions]]
777=== Framebuffer Region Dependencies
778
779<<synchronization-pipeline-stages, Pipeline stages>> that operate on, or
780with respect to, the framebuffer are collectively the _framebuffer-space_
781pipeline stages.
782These stages are:
783
784  * ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
785  * ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
786  * ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
787  * ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
788
789For these pipeline stages, an execution or memory dependency from the first
790set of operations to the second set can: either be a single
791_framebuffer-global_ dependency, or split into multiple _framebuffer-local_
792dependencies.
793A dependency with non-framebuffer-space pipeline stages is neither
794framebuffer-global nor framebuffer-local.
795
796A _framebuffer region_ is a set of sample (x, y, layer, sample) coordinates
797that is a subset of the entire framebuffer.
798
799Both <<synchronization-dependencies-scopes, synchronization scopes>> of a
800framebuffer-local dependency include only the operations performed within
801corresponding framebuffer regions (as defined below).
802No ordering guarantees are made between different framebuffer regions for a
803framebuffer-local dependency.
804
805Both <<synchronization-dependencies-scopes, synchronization scopes>> of a
806framebuffer-global dependency include operations on all framebuffer-regions.
807
808If the first synchronization scope includes operations on pixels/fragments
809with N samples and the second synchronization scope includes operations on
810pixels/fragments with M samples, where N does not equal M, then a
811framebuffer region containing all samples at a given (x, y, layer)
812coordinate in the first synchronization scope corresponds to a region
813containing all samples at the same coordinate in the second synchronization
814scope.
815In other words, it is a pixel granularity dependency.
816If N equals M, then a framebuffer region containing a single (x, y, layer,
817sample) coordinate in the first synchronization scope corresponds to a
818region containing the same sample at the same coordinate in the second
819synchronization scope.
820In other words, it is a sample granularity dependency.
821
822[NOTE]
823.Note
824====
825Since fragment invocations are not specified to run in any particular
826groupings, the size of a framebuffer region is implementation-dependent, not
827known to the application, and must: be assumed to be no larger than
828specified above.
829====
830
831[NOTE]
832.Note
833====
834Practically, the pixel vs sample granularity dependency means that if an
835input attachment has a different number of samples than the pipeline's
836pname:rasterizationSamples, then a fragment can: access any sample in the
837input attachment's pixel even if it only uses framebuffer-local
838dependencies.
839If the input attachment has the same number of samples, then the fragment
840can: only access the covered samples in its input code:SampleMask (i.e. the
841fragment operations happen-after a framebuffer-local dependency for each
842sample the fragment covers).
843To access samples that are not covered, a framebuffer-global dependency is
844required.
845====
846
847If a synchronization command includes a pname:dependencyFlags parameter, and
848specifies the ename:VK_DEPENDENCY_BY_REGION_BIT flag, then it defines
849framebuffer-local dependencies for the framebuffer-space pipeline stages in
850that synchronization command, for all framebuffer regions.
851If no pname:dependencyFlags parameter is included, or the
852ename:VK_DEPENDENCY_BY_REGION_BIT flag is not specified, then a
853framebuffer-global dependency is specified for those stages.
854The ename:VK_DEPENDENCY_BY_REGION_BIT flag does not affect the dependencies
855between non-framebuffer-space pipeline stages, nor does it affect the
856dependencies between framebuffer-space and non-framebuffer-space pipeline
857stages.
858
859[NOTE]
860.Note
861====
862Framebuffer-local dependencies are more optimal for most architectures;
863particularly tile-based architectures - which can keep framebuffer-regions
864entirely in on-chip registers and thus avoid external bandwidth across such
865a dependency.
866Including a framebuffer-global dependency in your rendering will usually
867force all implementations to flush data to memory, or to a higher level
868cache, breaking any potential locality optimizations.
869====
870
871
872ifdef::VK_VERSION_1_1,VK_KHR_multiview[]
873
874[[synchronization-view-local-dependencies]]
875=== View-Local Dependencies
876
877In a render pass instance that has <<renderpass-multiview,multiview>>
878enabled, dependencies can: be either view-local or view-global.
879
880A view-local dependency only includes operations from a single
881<<renderpass-multiview-view-local,source view>> from the source subpass in
882the first synchronization scope, and only includes operations from a single
883<<renderpass-multiview-view-local,destination view>> from the destination
884subpass in the second synchronization scope.
885A view-global dependency includes all views in the view mask of the source
886and destination subpasses in the corresponding synchronization scopes.
887
888If a synchronization command includes a pname:dependencyFlags parameter and
889specifies the ename:VK_DEPENDENCY_VIEW_LOCAL_BIT flag, then it defines
890view-local dependencies for that synchronization command, for all views.
891If no pname:dependencyFlags parameter is included or the
892ename:VK_DEPENDENCY_VIEW_LOCAL_BIT flag is not specified, then a view-global
893dependency is specified.
894
895endif::VK_VERSION_1_1,VK_KHR_multiview[]
896
897
898ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
899
900[[synchronization-device-local-dependencies]]
901=== Device-Local Dependencies
902
903Dependencies can: be either device-local or non-device-local.
904A device-local dependency acts as multiple separate dependencies, one for
905each physical device that executes the synchronization command, where each
906dependency only includes operations from that physical device in both
907synchronization scopes.
908A non-device-local dependency is a single dependency where both
909synchronization scopes include operations from all physical devices that
910participate in the synchronization command.
911For subpass dependencies, all physical devices in the
912slink:VkDeviceGroupRenderPassBeginInfo::pname:deviceMask participate in the
913dependency, and for pipeline barriers all physical devices that are set in
914the command buffer's current device mask participate in the dependency.
915
916If a synchronization command includes a pname:dependencyFlags parameter and
917specifies the ename:VK_DEPENDENCY_DEVICE_GROUP_BIT flag, then it defines a
918non-device-local dependency for that synchronization command.
919If no pname:dependencyFlags parameter is included or the
920ename:VK_DEPENDENCY_DEVICE_GROUP_BIT flag is not specified, then it defines
921device-local dependencies for that synchronization command, for all
922participating physical devices.
923
924Semaphore and event dependencies are device-local and only execute on the
925one physical device that performs the dependency.
926
927endif::VK_VERSION_1_1,VK_KHR_device_group[]
928
929
930[[synchronization-implicit]]
931== Implicit Synchronization Guarantees
932
933A small number of implicit ordering guarantees are provided by Vulkan,
934ensuring that the order in which commands are submitted is meaningful, and
935avoiding unnecessary complexity in common operations.
936
937[[synchronization-submission-order]]
938_Submission order_ is a fundamental ordering in Vulkan, giving meaning to
939the order in which <<fundamentals-queueoperation-command-types, action and
940synchronization commands>> are recorded and submitted to a single queue.
941Explicit and implicit ordering guarantees between commands in Vulkan all
942work on the premise that this ordering is meaningful.
943This order does not itself define any execution or memory dependencies;
944synchronization commands and other orderings within the API use this
945ordering to define their scopes.
946
947Submission order for any given set of commands is based on the order in
948which they were recorded to command buffers and then submitted.
949This order is determined as follows:
950
951  . The initial order is determined by the order in which
952    flink:vkQueueSubmit commands are executed on the host, for a single
953    queue, from first to last.
954  . The order in which slink:VkSubmitInfo structures are specified in the
955    pname:pSubmits parameter of flink:vkQueueSubmit, from lowest index to
956    highest.
957  . The order in which command buffers are specified in the
958    pname:pCommandBuffers member of slink:VkSubmitInfo, from lowest index to
959    highest.
960  . The order in which commands were recorded to a command buffer on the
961    host, from first to last:
962  ** For commands recorded outside a render pass, this includes all other
963     commands recorded outside a render pass, including
964     flink:vkCmdBeginRenderPass and flink:vkCmdEndRenderPass commands; it
965     does not directly include commands inside a render pass.
966  ** For commands recorded inside a render pass, this includes all other
967     commands recorded inside the same subpass, including the
968     flink:vkCmdBeginRenderPass and flink:vkCmdEndRenderPass commands that
969     delimit the same render pass instance; it does not include commands
970     recorded to other subpasses.
971
972<<fundamentals-queueoperation-command-types, Action and synchronization
973commands>> recorded to a command buffer execute the
974ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT pipeline stage in
975<<synchronization-submission-order, submission order>> - forming an implicit
976execution dependency between this stage in each command.
977
978<<fundamentals-queueoperation-command-types, State commands>> do not execute
979any operations on the device, instead they set the state of the command
980buffer when they execute on the host, in the order that they are recorded.
981<<fundamentals-queueoperation-command-types, Action commands>> consume the
982current state of the command buffer when they are recorded, and will execute
983state changes on the device as required to match the recorded state.
984
985<<queries-order, Query commands>>, <<drawing-primitive-order, the order of
986primitives passing through the graphics pipeline>> and
987<<synchronization-image-barrier-layout-transition-order, image layout
988transitions as part of an image memory barrier>> provide additional
989guarantees based on submission order.
990
991Execution of <<synchronization-pipeline-stages-order, pipeline stages>>
992within a given command also has a loose ordering, dependent only on a single
993command.
994
995
996[[synchronization-fences]]
997== Fences
998
999[open,refpage='VkFence',desc='Opaque handle to a fence object',type='handles']
1000--
1001
1002Fences are a synchronization primitive that can: be used to insert a
1003dependency from a queue to the host.
1004Fences have two states - signaled and unsignaled.
1005A fence can: be signaled as part of the execution of a
1006<<devsandqueues-submission, queue submission>> command.
1007Fences can: be unsignaled on the host with flink:vkResetFences.
1008Fences can: be waited on by the host with the flink:vkWaitForFences command,
1009and the current state can: be queried with flink:vkGetFenceStatus.
1010
1011ifdef::VK_VERSION_1_1,VK_KHR_external_fence[]
1012[[synchronization-fences-payloads]]
1013As with most objects in Vulkan, fences are an interface to internal data
1014which is typically opaque to applications.
1015This internal data is referred to as a fence's _payload_.
1016
1017However, in order to enable communication with agents outside of the current
1018device, it is necessary to be able to export that payload to a commonly
1019understood format, and subsequently import from that format as well.
1020
1021The internal data of a fence may: include a reference to any resources and
1022pending work associated with signal or unsignal operations performed on that
1023fence object.
1024Mechanisms to import and export that internal data to and from fences are
1025provided <<VkExportFenceCreateInfo, below>>.
1026These mechanisms indirectly enable applications to share fence state between
1027two or more fences and other synchronization primitives across process and
1028API boundaries.
1029
1030endif::VK_VERSION_1_1,VK_KHR_external_fence[]
1031
1032Fences are represented by sname:VkFence handles:
1033
1034include::../api/handles/VkFence.txt[]
1035
1036--
1037
1038[open,refpage='vkCreateFence',desc='Create a new fence object',type='protos']
1039--
1040
1041To create a fence, call:
1042
1043include::../api/protos/vkCreateFence.txt[]
1044
1045  * pname:device is the logical device that creates the fence.
1046  * pname:pCreateInfo is a pointer to an instance of the
1047    sname:VkFenceCreateInfo structure which contains information about how
1048    the fence is to be created.
1049  * pname:pAllocator controls host memory allocation as described in the
1050    <<memory-allocation, Memory Allocation>> chapter.
1051  * pname:pFence points to a handle in which the resulting fence object is
1052    returned.
1053
1054include::../validity/protos/vkCreateFence.txt[]
1055--
1056
1057[open,refpage='VkFenceCreateInfo',desc='Structure specifying parameters of a newly created fence',type='structs']
1058--
1059
1060The sname:VkFenceCreateInfo structure is defined as:
1061
1062include::../api/structs/VkFenceCreateInfo.txt[]
1063
1064  * pname:sType is the type of this structure.
1065  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
1066  * pname:flags is a bitmask of elink:VkFenceCreateFlagBits specifying the
1067    initial state and behavior of the fence.
1068
1069include::../validity/structs/VkFenceCreateInfo.txt[]
1070--
1071
1072[open,refpage='VkFenceCreateFlagBits',desc='Bitmask specifying initial state and behavior of a fence',type='enums']
1073--
1074
1075include::../api/enums/VkFenceCreateFlagBits.txt[]
1076
1077  * ename:VK_FENCE_CREATE_SIGNALED_BIT specifies that the fence object is
1078    created in the signaled state.
1079    Otherwise, it is created in the unsignaled state.
1080
1081--
1082
1083[open,refpage='VkFenceCreateFlags',desc='Bitmask of VkFenceCreateFlagBits',type='enums']
1084--
1085include::../api/flags/VkFenceCreateFlags.txt[]
1086
1087sname:VkFenceCreateFlags is a bitmask type for setting a mask of zero or
1088more slink:VkFenceCreateFlagBits.
1089--
1090
1091ifdef::VK_VERSION_1_1,VK_KHR_external_fence[]
1092
1093[open,refpage='VkExportFenceCreateInfo',desc='Structure specifying handle types that can be exported from a fence',type='structs']
1094--
1095
1096To create a fence whose payload can: be exported to external handles, add
1097the slink:VkExportFenceCreateInfo structure to the pname:pNext chain of the
1098slink:VkFenceCreateInfo structure.
1099The sname:VkExportFenceCreateInfo structure is defined as:
1100
1101include::../api/structs/VkExportFenceCreateInfo.txt[]
1102
1103ifdef::VK_KHR_external_fence[]
1104or the equivalent
1105
1106include::../api/structs/VkExportFenceCreateInfoKHR.txt[]
1107endif::VK_KHR_external_fence[]
1108
1109  * pname:sType is the type of this structure.
1110  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
1111  * pname:handleTypes is a bitmask of
1112    elink:VkExternalFenceHandleTypeFlagBits specifying one or more fence
1113    handle types the application can: export from the resulting fence.
1114    The application can: request multiple handle types for the same fence.
1115
1116.Valid Usage
1117****
1118  * [[VUID-VkExportFenceCreateInfo-handleTypes-01446]]
1119    The bits in pname:handleTypes must be supported and compatible, as
1120    reported by slink:VkExternalFenceProperties.
1121****
1122
1123include::../validity/structs/VkExportFenceCreateInfo.txt[]
1124--
1125
1126endif::VK_VERSION_1_1,VK_KHR_external_fence[]
1127
1128ifdef::VK_KHR_external_fence_win32[]
1129
1130[open,refpage='VkExportFenceWin32HandleInfoKHR',desc='Structure specifying additional attributes of Windows handles exported from a fence',type='structs']
1131--
1132
1133To specify additional attributes of NT handles exported from a fence, add
1134the slink:VkExportFenceWin32HandleInfoKHR structure to the pname:pNext chain
1135of the slink:VkFenceCreateInfo structure.
1136The sname:VkExportFenceWin32HandleInfoKHR structure is defined as:
1137
1138include::../api/structs/VkExportFenceWin32HandleInfoKHR.txt[]
1139
1140  * pname:sType is the type of this structure.
1141  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
1142  * pname:pAttributes is a pointer to a Windows code:SECURITY_ATTRIBUTES
1143    structure specifying security attributes of the handle.
1144  * pname:dwAccess is a code:DWORD specifying access rights of the handle.
1145  * pname:name is a NULL-terminated UTF-16 string to associate with the
1146    underlying synchronization primitive referenced by NT handles exported
1147    from the created fence.
1148
1149If this structure is not present, or if pname:pAttributes is set to `NULL`,
1150default security descriptor values will be used, and child processes created
1151by the application will not inherit the handle, as described in the MSDN
1152documentation for "`Synchronization Object Security and Access Rights`"^1^.
1153Further, if the structure is not present, the access rights will be
1154
1155code:DXGI_SHARED_RESOURCE_READ | code:DXGI_SHARED_RESOURCE_WRITE
1156
1157for handles of the following types:
1158
1159ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
1160
11611::
1162    https://msdn.microsoft.com/en-us/library/windows/desktop/ms686670.aspx
1163
1164.Valid Usage
1165****
1166  * [[VUID-VkExportFenceWin32HandleInfoKHR-handleTypes-01447]]
1167    If slink:VkExportFenceCreateInfo::pname:handleTypes does not include
1168    ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT,
1169    sname:VkExportFenceWin32HandleInfoKHR must: not be in the pname:pNext
1170    chain of slink:VkFenceCreateInfo.
1171****
1172
1173include::../validity/structs/VkExportFenceWin32HandleInfoKHR.txt[]
1174--
1175
1176[open,refpage='vkGetFenceWin32HandleKHR',desc='Get a Windows HANDLE for a fence',type='protos']
1177--
1178
1179To export a Windows handle representing the state of a fence, call:
1180
1181include::../api/protos/vkGetFenceWin32HandleKHR.txt[]
1182
1183  * pname:device is the logical device that created the fence being
1184    exported.
1185  * pname:pGetWin32HandleInfo is a pointer to an instance of the
1186    slink:VkFenceGetWin32HandleInfoKHR structure containing parameters of
1187    the export operation.
1188  * pname:pHandle will return the Windows handle representing the fence
1189    state.
1190
1191For handle types defined as NT handles, the handles returned by
1192fname:vkGetFenceWin32HandleKHR are owned by the application.
1193To avoid leaking resources, the application must: release ownership of them
1194using the fname:CloseHandle system call when they are no longer needed.
1195
1196Exporting a Windows handle from a fence may: have side effects depending on
1197the transference of the specified handle type, as described in
1198<<synchronization-fences-importing,Importing Fence Payloads>>.
1199
1200include::../validity/protos/vkGetFenceWin32HandleKHR.txt[]
1201--
1202
1203[open,refpage='VkFenceGetWin32HandleInfoKHR',desc='Structure describing a Win32 handle fence export operation',type='structs']
1204--
1205
1206The sname:VkFenceGetWin32HandleInfoKHR structure is defined as:
1207
1208include::../api/structs/VkFenceGetWin32HandleInfoKHR.txt[]
1209
1210  * pname:sType is the type of this structure.
1211  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
1212  * pname:fence is the fence from which state will be exported.
1213  * pname:handleType is the type of handle requested.
1214
1215The properties of the handle returned depend on the value of
1216pname:handleType.
1217See elink:VkExternalFenceHandleTypeFlagBits for a description of the
1218properties of the defined external fence handle types.
1219
1220.Valid Usage
1221****
1222  * [[VUID-VkFenceGetWin32HandleInfoKHR-handleType-01448]]
1223    pname:handleType must: have been included in
1224    slink:VkExportFenceCreateInfo::pname:handleTypes when the pname:fence's
1225    current payload was created.
1226  * [[VUID-VkFenceGetWin32HandleInfoKHR-handleType-01449]]
1227    If pname:handleType is defined as an NT handle,
1228    flink:vkGetFenceWin32HandleKHR must: be called no more than once for
1229    each valid unique combination of pname:fence and pname:handleType.
1230  * [[VUID-VkFenceGetWin32HandleInfoKHR-fence-01450]]
1231    pname:fence must: not currently have its payload replaced by an imported
1232    payload as described below in
1233    <<synchronization-fences-importing,Importing Fence Payloads>> unless
1234    that imported payload's handle type was included in
1235    slink:VkExternalFenceProperties::pname:exportFromImportedHandleTypes for
1236    pname:handleType.
1237  * [[VUID-VkFenceGetWin32HandleInfoKHR-handleType-01451]]
1238    If pname:handleType refers to a handle type with copy payload
1239    transference semantics, pname:fence must: be signaled, or have an
1240    associated <<synchronization-fences-signaling,fence signal operation>>
1241    pending execution.
1242  * [[VUID-VkFenceGetWin32HandleInfoKHR-handleType-01452]]
1243    pname:handleType must: be defined as an NT handle or a global share
1244    handle.
1245****
1246
1247include::../validity/structs/VkFenceGetWin32HandleInfoKHR.txt[]
1248--
1249
1250endif::VK_KHR_external_fence_win32[]
1251
1252ifdef::VK_KHR_external_fence_fd[]
1253
1254[open,refpage='vkGetFenceFdKHR',desc='Get a POSIX file descriptor handle for a fence',type='protos']
1255--
1256
1257To export a POSIX file descriptor representing the payload of a fence, call:
1258
1259include::../api/protos/vkGetFenceFdKHR.txt[]
1260
1261  * pname:device is the logical device that created the fence being
1262    exported.
1263  * pname:pGetFdInfo is a pointer to an instance of the
1264    slink:VkFenceGetFdInfoKHR structure containing parameters of the export
1265    operation.
1266  * pname:pFd will return the file descriptor representing the fence
1267    payload.
1268
1269Each call to fname:vkGetFenceFdKHR must: create a new file descriptor and
1270transfer ownership of it to the application.
1271To avoid leaking resources, the application must: release ownership of the
1272file descriptor when it is no longer needed.
1273
1274[NOTE]
1275.Note
1276====
1277Ownership can be released in many ways.
1278For example, the application can call code:close() on the file descriptor,
1279or transfer ownership back to Vulkan by using the file descriptor to import
1280a fence payload.
1281====
1282
1283If pname:pGetFdInfo\->pname:handleType is
1284ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT and the fence is signaled at
1285the time fname:vkGetFenceFdKHR is called, pname:pFd may: return the value
1286`-1` instead of a valid file descriptor.
1287
1288Where supported by the operating system, the implementation must: set the
1289file descriptor to be closed automatically when an code:execve system call
1290is made.
1291
1292Exporting a file descriptor from a fence may: have side effects depending on
1293the transference of the specified handle type, as described in
1294<<synchronization-fences-importing,Importing Fence State>>.
1295
1296include::../validity/protos/vkGetFenceFdKHR.txt[]
1297--
1298
1299[open,refpage='VkFenceGetFdInfoKHR',desc='Structure describing a POSIX FD fence export operation',type='structs']
1300--
1301
1302The sname:VkFenceGetFdInfoKHR structure is defined as:
1303
1304include::../api/structs/VkFenceGetFdInfoKHR.txt[]
1305
1306  * pname:sType is the type of this structure.
1307  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
1308  * pname:fence is the fence from which state will be exported.
1309  * pname:handleType is the type of handle requested.
1310
1311The properties of the file descriptor returned depend on the value of
1312pname:handleType.
1313See elink:VkExternalFenceHandleTypeFlagBits for a description of the
1314properties of the defined external fence handle types.
1315
1316.Valid Usage
1317****
1318  * [[VUID-VkFenceGetFdInfoKHR-handleType-01453]]
1319    pname:handleType must: have been included in
1320    slink:VkExportFenceCreateInfo::pname:handleTypes when pname:fence's
1321    current payload was created.
1322  * [[VUID-VkFenceGetFdInfoKHR-handleType-01454]]
1323    If pname:handleType refers to a handle type with copy payload
1324    transference semantics, pname:fence must: be signaled, or have an
1325    associated <<synchronization-fences-signaling,fence signal operation>>
1326    pending execution.
1327  * [[VUID-VkFenceGetFdInfoKHR-fence-01455]]
1328    pname:fence must: not currently have its payload replaced by an imported
1329    payload as described below in
1330    <<synchronization-fences-importing,Importing Fence Payloads>> unless
1331    that imported payload's handle type was included in
1332    slink:VkExternalFenceProperties::pname:exportFromImportedHandleTypes for
1333    pname:handleType.
1334  * [[VUID-VkFenceGetFdInfoKHR-handleType-01456]]
1335    pname:handleType must: be defined as a POSIX file descriptor handle.
1336****
1337
1338include::../validity/structs/VkFenceGetFdInfoKHR.txt[]
1339--
1340
1341endif::VK_KHR_external_fence_fd[]
1342
1343[open,refpage='vkDestroyFence',desc='Destroy a fence object',type='protos']
1344--
1345
1346To destroy a fence, call:
1347
1348include::../api/protos/vkDestroyFence.txt[]
1349
1350  * pname:device is the logical device that destroys the fence.
1351  * pname:fence is the handle of the fence to destroy.
1352  * pname:pAllocator controls host memory allocation as described in the
1353    <<memory-allocation, Memory Allocation>> chapter.
1354
1355.Valid Usage
1356****
1357  * [[VUID-vkDestroyFence-fence-01120]]
1358    All <<devsandqueues-submission, queue submission>> commands that refer
1359    to pname:fence must: have completed execution
1360  * [[VUID-vkDestroyFence-fence-01121]]
1361    If sname:VkAllocationCallbacks were provided when pname:fence was
1362    created, a compatible set of callbacks must: be provided here
1363  * [[VUID-vkDestroyFence-fence-01122]]
1364    If no sname:VkAllocationCallbacks were provided when pname:fence was
1365    created, pname:pAllocator must: be `NULL`
1366****
1367
1368include::../validity/protos/vkDestroyFence.txt[]
1369--
1370
1371[open,refpage='vkGetFenceStatus',desc='Return the status of a fence',type='protos']
1372--
1373
1374To query the status of a fence from the host, call:
1375
1376include::../api/protos/vkGetFenceStatus.txt[]
1377
1378  * pname:device is the logical device that owns the fence.
1379  * pname:fence is the handle of the fence to query.
1380
1381Upon success, fname:vkGetFenceStatus returns the status of the fence object,
1382with the following return codes:
1383
1384.Fence Object Status Codes
1385[width="80%",options="header"]
1386|====
1387| Status | Meaning
1388| ename:VK_SUCCESS | The fence specified by pname:fence is signaled.
1389| ename:VK_NOT_READY | The fence specified by pname:fence is unsignaled.
1390| ename:VK_ERROR_DEVICE_LOST | The device has been lost.  See <<devsandqueues-lost-device,Lost Device>>.
1391|====
1392
1393If a <<devsandqueues-submission, queue submission>> command is pending
1394execution, then the value returned by this command may: immediately be out
1395of date.
1396
1397If the device has been lost (see <<devsandqueues-lost-device,Lost Device>>),
1398fname:vkGetFenceStatus may: return any of the above status codes.
1399If the device has been lost and fname:vkGetFenceStatus is called repeatedly,
1400it will eventually return either ename:VK_SUCCESS or
1401ename:VK_ERROR_DEVICE_LOST.
1402
1403include::../validity/protos/vkGetFenceStatus.txt[]
1404--
1405
1406[[synchronization-fences-unsignaling]]
1407[open,refpage='vkResetFences',desc='Resets one or more fence objects',type='protos']
1408--
1409
1410To set the state of fences to unsignaled from the host, call:
1411
1412include::../api/protos/vkResetFences.txt[]
1413
1414  * pname:device is the logical device that owns the fences.
1415  * pname:fenceCount is the number of fences to reset.
1416  * pname:pFences is a pointer to an array of fence handles to reset.
1417
1418ifdef::VK_VERSION_1_1,VK_KHR_external_fence[]
1419
1420If any member of pname:pFences currently has its
1421<<synchronization-fences-importing, payload imported>> with temporary
1422permanence, that fence's prior permanent payload is first restored.
1423The remaining operations described therefore operate on the restored
1424payload.
1425
1426endif::VK_VERSION_1_1,VK_KHR_external_fence[]
1427
1428When flink:vkResetFences is executed on the host, it defines a _fence
1429unsignal operation_ for each fence, which resets the fence to the unsignaled
1430state.
1431
1432If any member of pname:pFences is already in the unsignaled state when
1433flink:vkResetFences is executed, then flink:vkResetFences has no effect on
1434that fence.
1435
1436.Valid Usage
1437****
1438  * [[VUID-vkResetFences-pFences-01123]]
1439    Each element of pname:pFences must: not be currently associated with any
1440    queue command that has not yet completed execution on that queue
1441****
1442
1443include::../validity/protos/vkResetFences.txt[]
1444--
1445
1446[[synchronization-fences-signaling]]
1447When a fence is submitted to a queue as part of a
1448<<devsandqueues-submission, queue submission>> command, it defines a memory
1449dependency on the batches that were submitted as part of that command, and
1450defines a _fence signal operation_ which sets the fence to the signaled
1451state.
1452
1453The first <<synchronization-dependencies-scopes, synchronization scope>>
1454includes every batch submitted in the same <<devsandqueues-submission, queue
1455submission>> command.
1456Fence signal operations that are defined by flink:vkQueueSubmit additionally
1457include in the first synchronization scope all commands that occur earlier
1458in <<synchronization-submission-order,submission order>>.
1459
1460The second <<synchronization-dependencies-scopes, synchronization scope>>
1461only includes the fence signal operation.
1462
1463The first <<synchronization-dependencies-access-scopes, access scope>>
1464includes all memory access performed by the device.
1465
1466The second <<synchronization-dependencies-access-scopes, access scope>> is
1467empty.
1468
1469[open,refpage='vkWaitForFences',desc='Wait for one or more fences to become signaled',type='protos']
1470--
1471
1472To wait for one or more fences to enter the signaled state on the host,
1473call:
1474
1475include::../api/protos/vkWaitForFences.txt[]
1476
1477  * pname:device is the logical device that owns the fences.
1478  * pname:fenceCount is the number of fences to wait on.
1479  * pname:pFences is a pointer to an array of pname:fenceCount fence
1480    handles.
1481  * pname:waitAll is the condition that must: be satisfied to successfully
1482    unblock the wait.
1483    If pname:waitAll is ename:VK_TRUE, then the condition is that all fences
1484    in pname:pFences are signaled.
1485    Otherwise, the condition is that at least one fence in pname:pFences is
1486    signaled.
1487  * pname:timeout is the timeout period in units of nanoseconds.
1488    pname:timeout is adjusted to the closest value allowed by the
1489    implementation-dependent timeout accuracy, which may: be substantially
1490    longer than one nanosecond, and may: be longer than the requested
1491    period.
1492
1493If the condition is satisfied when fname:vkWaitForFences is called, then
1494fname:vkWaitForFences returns immediately.
1495If the condition is not satisfied at the time fname:vkWaitForFences is
1496called, then fname:vkWaitForFences will block and wait up to pname:timeout
1497nanoseconds for the condition to become satisfied.
1498
1499If pname:timeout is zero, then fname:vkWaitForFences does not wait, but
1500simply returns the current state of the fences.
1501ename:VK_TIMEOUT will be returned in this case if the condition is not
1502satisfied, even though no actual wait was performed.
1503
1504If the specified timeout period expires before the condition is satisfied,
1505fname:vkWaitForFences returns ename:VK_TIMEOUT.
1506If the condition is satisfied before pname:timeout nanoseconds has expired,
1507fname:vkWaitForFences returns ename:VK_SUCCESS.
1508
1509If device loss occurs (see <<devsandqueues-lost-device,Lost Device>>) before
1510the timeout has expired, fname:vkWaitForFences must: return in finite time
1511with either ename:VK_SUCCESS or ename:VK_ERROR_DEVICE_LOST.
1512
1513[NOTE]
1514.Note
1515====
1516While we guarantee that fname:vkWaitForFences must: return in finite time,
1517no guarantees are made that it returns immediately upon device loss.
1518However, the client can reasonably expect that the delay will be on the
1519order of seconds and that calling fname:vkWaitForFences will not result in a
1520permanently (or seemingly permanently) dead process.
1521====
1522
1523include::../validity/protos/vkWaitForFences.txt[]
1524--
1525
1526[[synchronization-fences-waiting]]
1527An execution dependency is defined by waiting for a fence to become
1528signaled, either via flink:vkWaitForFences or by polling on
1529flink:vkGetFenceStatus.
1530
1531The first <<synchronization-dependencies-scopes, synchronization scope>>
1532includes only the fence signal operation.
1533
1534The second <<synchronization-dependencies-scopes, synchronization scope>>
1535includes the host operations of flink:vkWaitForFences or
1536flink:vkGetFenceStatus indicating that the fence has become signaled.
1537
1538[NOTE]
1539.Note
1540====
1541Signaling a fence and waiting on the host does not guarantee that the
1542results of memory accesses will be visible to the host, as the access scope
1543of a memory dependency defined by a fence only includes device access.
1544A <<synchronization-memory-barriers, memory barrier>> or other memory
1545dependency must: be used to guarantee this.
1546See the description of <<synchronization-host-access-types, host access
1547types>> for more information.
1548====
1549
1550ifdef::VK_EXT_display_control[]
1551include::VK_EXT_display_control/fence_events.txt[]
1552endif::VK_EXT_display_control[]
1553
1554
1555ifdef::VK_VERSION_1_1,VK_KHR_external_fence[]
1556
1557[[synchronization-fences-importing]]
1558=== Importing Fence Payloads
1559
1560Applications can: import a fence payload into an existing fence using an
1561external fence handle.
1562The effects of the import operation will be either temporary or permanent,
1563as specified by the application.
1564If the import is temporary, the fence will be _restored_ to its permanent
1565state the next time that fence is passed to flink:vkResetFences.
1566
1567[NOTE]
1568.Note
1569====
1570Restoring a fence to its prior permanent payload is a distinct operation
1571from resetting a fence payload.
1572See flink:vkResetFences for more detail.
1573====
1574
1575Performing a subsequent temporary import on a fence before resetting it has
1576no effect on this requirement; the next unsignal of the fence must: still
1577restore its last permanent state.
1578A permanent payload import behaves as if the target fence was destroyed, and
1579a new fence was created with the same handle but the imported payload.
1580Because importing a fence payload temporarily or permanently detaches the
1581existing payload from a fence, similar usage restrictions to those applied
1582to fname:vkDestroyFence are applied to any command that imports a fence
1583payload.
1584Which of these import types is used is referred to as the import operation's
1585_permanence_.
1586Each handle type supports either one or both types of permanence.
1587
1588The implementation must: perform the import operation by either referencing
1589or copying the payload referred to by the specified external fence handle,
1590depending on the handle's type.
1591The import method used is referred to as the handle type's _transference_.
1592When using handle types with reference transference, importing a payload to
1593a fence adds the fence to the set of all fences sharing that payload.
1594This set includes the fence from which the payload was exported.
1595Fence signaling, waiting, and resetting operations performed on any fence in
1596the set must: behave as if the set were a single fence.
1597Importing a payload using handle types with copy transference creates a
1598duplicate copy of the payload at the time of import, but makes no further
1599reference to it.
1600Fence signaling, waiting, and resetting operations performed on the target
1601of copy imports must: not affect any other fence or payload.
1602
1603Export operations have the same transference as the specified handle type's
1604import operations.
1605Additionally, exporting a fence payload to a handle with copy transference
1606has the same side effects on the source fence's payload as executing a fence
1607reset operation.
1608If the fence was using a temporarily imported payload, the fence's prior
1609permanent payload will be restored.
1610
1611ifdef::VK_KHR_external_fence_win32,VK_KHR_external_fence_fd[]
1612[NOTE]
1613.Note
1614====
1615The
1616ifdef::VK_KHR_external_fence_win32+VK_KHR_external_fence_fd[tables]
1617ifndef::VK_KHR_external_fence_win32+VK_KHR_external_fence_fd[table]
1618ifdef::VK_KHR_external_fence_win32[]
1619<<synchronization-fence-handletypes-win32,Handle Types Supported by
1620VkImportFenceWin32HandleInfoKHR>>
1621endif::VK_KHR_external_fence_win32[]
1622ifdef::VK_KHR_external_fence_win32+VK_KHR_external_fence_fd[and]
1623ifdef::VK_KHR_external_fence_fd[]
1624<<synchronization-fence-handletypes-fd,Handle Types Supported by
1625VkImportFenceFdInfoKHR>>
1626endif::VK_KHR_external_fence_fd[]
1627ifdef::VK_KHR_external_fence_win32+VK_KHR_external_fence_fd[define]
1628ifndef::VK_KHR_external_fence_win32+VK_KHR_external_fence_fd[defines]
1629the permanence and transference of each handle type.
1630====
1631endif::VK_KHR_external_fence_win32,VK_KHR_external_fence_fd[]
1632
1633<<fundamentals-threadingbehavior,External synchronization>> allows
1634implementations to modify an object's internal state, i.e. payload, without
1635internal synchronization.
1636However, for fences sharing a payload across processes, satisfying the
1637external synchronization requirements of fname:VkFence parameters as if all
1638fences in the set were the same object is sometimes infeasible.
1639Satisfying valid usage constraints on the state of a fence would similarly
1640require impractical coordination or levels of trust between processes.
1641Therefore, these constraints only apply to a specific fence handle, not to
1642its payload.
1643For distinct fence objects which share a payload:
1644
1645* If multiple commands which queue a signal operation, or which unsignal a
1646fence, are called concurrently, behavior will be as if the commands were
1647called in an arbitrary sequential order.
1648* If a queue submission command is called with a fence that is sharing a
1649payload, and the payload is already associated with another queue command
1650that has not yet completed execution, either one or both of the commands
1651will cause the fence to become signaled when they complete execution.
1652* If a fence payload is reset while it is associated with a queue command
1653that has not yet completed execution, the payload will become unsignaled,
1654but may: become signaled again when the command completes execution.
1655* In the preceding cases, any of the devices associated with the fences
1656sharing the payload may: be lost, or any of the queue submission or fence
1657reset commands may: return ename:VK_ERROR_INITIALIZATION_FAILED.
1658
1659Other than these non-deterministic results, behavior is well defined.
1660In particular:
1661
1662* The implementation must: not crash or enter an internally inconsistent
1663state where future valid Vulkan commands might cause undefined results,
1664* Timeouts on future wait commands on fences sharing the payload must: be
1665effective.
1666
1667[NOTE]
1668.Note
1669====
1670These rules allow processes to synchronize access to shared memory without
1671trusting each other.
1672However, such processes must still be cautious not to use the shared fence
1673for more than synchronizing access to the shared memory.
1674For example, a process should not use a fence with shared payload to tell
1675when commands it submitted to a queue have completed and objects used by
1676those commands may be destroyed, since the other process can accidentally or
1677maliciously cause the fence to signal before the commands actually complete.
1678====
1679
1680When a fence is using an imported payload, its
1681slink:VkExportFenceCreateInfo::pname:handleTypes value is that specified
1682when creating the fence from which the payload was exported, rather than
1683that specified when creating the fence.
1684Additionally, slink:VkExternalFenceProperties::exportFromImportedHandleTypes
1685restricts which handle types can: be exported from such a fence based on the
1686specific handle type used to import the current payload.
1687ifdef::VK_KHR_swapchain[]
1688Passing a fence to flink:vkAcquireNextImageKHR is equivalent to temporarily
1689importing a fence payload to that fence.
1690
1691[NOTE]
1692.Note
1693====
1694Because the exportable handle types of an imported fence correspond to its
1695current imported payload, and flink:vkAcquireNextImageKHR behaves the same
1696as a temporary import operation for which the source fence is opaque to the
1697application, applications have no way of determining whether any external
1698handle types can: be exported from a fence in this state.
1699Therefore, applications must: not attempt to export handles from fences
1700using a temporarily imported payload from flink:vkAcquireNextImageKHR.
1701====
1702endif::VK_KHR_swapchain[]
1703
1704When importing a fence payload, it is the responsibility of the application
1705to ensure the external handles meet all valid usage requirements.
1706However, implementations must: perform sufficient validation of external
1707handles to ensure that the operation results in a valid fence which will not
1708cause program termination, device loss, queue stalls, host thread stalls, or
1709corruption of other resources when used as allowed according to its import
1710parameters.
1711If the external handle provided does not meet these requirements, the
1712implementation must: fail the fence payload import operation with the error
1713code ename:VK_ERROR_INVALID_EXTERNAL_HANDLE.
1714
1715endif::VK_VERSION_1_1,VK_KHR_external_fence[]
1716
1717ifdef::VK_KHR_external_fence_win32[]
1718
1719[open,refpage='vkImportFenceWin32HandleKHR',desc='Import a fence from a Windows HANDLE',type='protos']
1720--
1721
1722To import a fence payload from a Windows handle, call:
1723
1724include::../api/protos/vkImportFenceWin32HandleKHR.txt[]
1725
1726  * pname:device is the logical device that created the fence.
1727  * pname:pImportFenceWin32HandleInfo points to a
1728    slink:VkImportFenceWin32HandleInfoKHR structure specifying the fence and
1729    import parameters.
1730
1731Importing a fence payload from Windows handles does not transfer ownership
1732of the handle to the Vulkan implementation.
1733For handle types defined as NT handles, the application must: release
1734ownership using the fname:CloseHandle system call when the handle is no
1735longer needed.
1736
1737Applications can: import the same fence payload into multiple instances of
1738Vulkan, into the same instance from which it was exported, and multiple
1739times into a given Vulkan instance.
1740
1741include::../validity/protos/vkImportFenceWin32HandleKHR.txt[]
1742--
1743
1744[open,refpage='VkImportFenceWin32HandleInfoKHR',desc='(None)',type='structs']
1745--
1746The sname:VkImportFenceWin32HandleInfoKHR structure is defined as:
1747
1748include::../api/structs/VkImportFenceWin32HandleInfoKHR.txt[]
1749
1750  * pname:sType is the type of this structure.
1751  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
1752  * pname:fence is the fence into which the state will be imported.
1753  * pname:flags is a bitmask of elink:VkFenceImportFlagBits specifying
1754    additional parameters for the fence payload import operation.
1755  * pname:handleType specifies the type of pname:handle.
1756  * pname:handle is the external handle to import, or `NULL`.
1757  * pname:name is the NULL-terminated UTF-16 string naming the underlying
1758    synchronization primitive to import, or `NULL`.
1759
1760The handle types supported by pname:handleType are:
1761
1762[[synchronization-fence-handletypes-win32]]
1763.Handle Types Supported by VkImportFenceWin32HandleInfoKHR
1764[width="80%",options="header"]
1765|====
1766| Handle Type                                                  | Transference | Permanence Supported
1767| ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT     | Reference    | Temporary,Permanent
1768| ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT | Reference    | Temporary,Permanent
1769|====
1770
1771.Valid Usage
1772****
1773  * [[VUID-VkImportFenceWin32HandleInfoKHR-handleType-01457]]
1774    pname:handleType must: be a value included in the
1775    <<synchronization-fence-handletypes-win32, Handle Types Supported by
1776    VkImportFenceWin32HandleInfoKHR>> table.
1777  * [[VUID-VkImportFenceWin32HandleInfoKHR-handleType-01459]]
1778    If pname:handleType is not
1779    ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT, pname:name must:
1780    be `NULL`.
1781  * [[VUID-VkImportFenceWin32HandleInfoKHR-handleType-01460]]
1782    If pname:handleType is not `0` and pname:handle is `NULL`, pname:name
1783    must: name a valid synchronization primitive of the type specified by
1784    pname:handleType.
1785  * [[VUID-VkImportFenceWin32HandleInfoKHR-handleType-01461]]
1786    If pname:handleType is not `0` and pname:name is `NULL`, pname:handle
1787    must: be a valid handle of the type specified by pname:handleType.
1788  * [[VUID-VkImportFenceWin32HandleInfoKHR-handle-01462]]
1789    If pname:handle is not `NULL`, pname:name must be `NULL`.
1790  * [[VUID-VkImportFenceWin32HandleInfoKHR-handle-01539]]
1791    If pname:handle is not `NULL`, it must: obey any requirements listed for
1792    pname:handleType in <<external-fence-handle-types-compatibility,external
1793    fence handle types compatibility>>.
1794  * [[VUID-VkImportFenceWin32HandleInfoKHR-name-01540]]
1795    If pname:name is not `NULL`, it must: obey any requirements listed for
1796    pname:handleType in <<external-fence-handle-types-compatibility,external
1797    fence handle types compatibility>>.
1798****
1799
1800include::../validity/structs/VkImportFenceWin32HandleInfoKHR.txt[]
1801--
1802
1803endif::VK_KHR_external_fence_win32[]
1804
1805ifdef::VK_KHR_external_fence_fd[]
1806
1807[open,refpage='vkImportFenceFdKHR',desc='Import a fence from a POSIX file descriptor',type='protos']
1808--
1809
1810To import a fence payload from a POSIX file descriptor, call:
1811
1812include::../api/protos/vkImportFenceFdKHR.txt[]
1813
1814  * pname:device is the logical device that created the fence.
1815  * pname:pImportFenceFdInfo points to a slink:VkImportFenceFdInfoKHR
1816    structure specifying the fence and import parameters.
1817
1818Importing a fence payload from a file descriptor transfers ownership of the
1819file descriptor from the application to the Vulkan implementation.
1820The application must: not perform any operations on the file descriptor
1821after a successful import.
1822
1823Applications can: import the same fence payload into multiple instances of
1824Vulkan, into the same instance from which it was exported, and multiple
1825times into a given Vulkan instance.
1826
1827.Valid Usage
1828****
1829  * [[VUID-vkImportFenceFdKHR-fence-01463]]
1830    pname:fence must: not be associated with any queue command that has not
1831    yet completed execution on that queue
1832****
1833
1834include::../validity/protos/vkImportFenceFdKHR.txt[]
1835--
1836
1837[open,refpage='VkImportFenceFdInfoKHR',desc='(None)',type='structs']
1838--
1839The sname:VkImportFenceFdInfoKHR structure is defined as:
1840
1841include::../api/structs/VkImportFenceFdInfoKHR.txt[]
1842
1843  * pname:sType is the type of this structure.
1844  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
1845  * pname:fence is the fence into which the payload will be imported.
1846  * pname:flags is a bitmask of elink:VkFenceImportFlagBits specifying
1847    additional parameters for the fence payload import operation.
1848  * pname:handleType specifies the type of pname:fd.
1849  * pname:fd is the external handle to import.
1850
1851The handle types supported by pname:handleType are:
1852
1853[[synchronization-fence-handletypes-fd]]
1854.Handle Types Supported by VkImportFenceFdInfoKHR
1855[width="80%",options="header"]
1856|====
1857| Handle Type                                           | Transference | Permanence Supported
1858| ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT | Reference    | Temporary,Permanent
1859| ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT   | Copy         | Temporary
1860|====
1861
1862.Valid Usage
1863****
1864  * [[VUID-VkImportFenceFdInfoKHR-handleType-01464]]
1865    pname:handleType must: be a value included in the
1866    <<synchronization-fence-handletypes-fd, Handle Types Supported by
1867    VkImportFenceFdInfoKHR>> table.
1868  * [[VUID-VkImportFenceFdInfoKHR-fd-01541]]
1869    pname:fd must: obey any requirements listed for pname:handleType in
1870    <<external-fence-handle-types-compatibility,external fence handle types
1871    compatibility>>.
1872****
1873
1874If pname:handleType is ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT, the
1875special value `-1` for pname:fd is treated like a valid sync file descriptor
1876referring to an object that has already signaled.
1877The import operation will succeed and the sname:VkFence will have a
1878temporarily imported payload as if a valid file descriptor had been
1879provided.
1880
1881[NOTE]
1882.Note
1883====
1884This special behavior for importing an invalid sync file descriptor allows
1885easier interoperability with other system APIs which use the convention that
1886an invalid sync file descriptor represents work that has already completed
1887and does not need to be waited for.
1888It is consistent with the option for implementations to return a `-1` file
1889descriptor when exporting a ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
1890from a sname:VkFence which is signaled.
1891====
1892
1893include::../validity/structs/VkImportFenceFdInfoKHR.txt[]
1894--
1895
1896endif::VK_KHR_external_fence_fd[]
1897
1898ifdef::VK_VERSION_1_1,VK_KHR_external_fence[]
1899ifdef::VK_KHR_external_fence_win32,VK_KHR_external_fence_fd[]
1900
1901[open,refpage='VkFenceImportFlagBits',desc='Bitmask specifying additional parameters of fence payload import',type='enums']
1902--
1903
1904Bits which can: be set in
1905ifdef::VK_KHR_external_fence_win32[]
1906slink:VkImportFenceWin32HandleInfoKHR::pname:flags
1907endif::VK_KHR_external_fence_win32[]
1908ifdef::VK_KHR_external_fence_win32+VK_KHR_external_fence_fd[and]
1909ifdef::VK_KHR_external_fence_fd[]
1910slink:VkImportFenceFdInfoKHR::pname:flags
1911endif::VK_KHR_external_fence_fd[]
1912specifying additional parameters of a fence import operation are:
1913
1914include::../api/enums/VkFenceImportFlagBits.txt[]
1915
1916ifdef::VK_KHR_external_fence[]
1917or the equivalent
1918
1919include::../api/enums/VkFenceImportFlagBitsKHR.txt[]
1920endif::VK_KHR_external_fence[]
1921
1922  * ename:VK_FENCE_IMPORT_TEMPORARY_BIT specifies that the fence payload
1923    will be imported only temporarily, as described in
1924    <<synchronization-fences-importing,Importing Fence Payloads>>,
1925    regardless of the permanence of pname:handleType.
1926
1927--
1928
1929[open,refpage='VkFenceImportFlags',desc='Bitmask of VkFenceImportFlagBits',type='enums']
1930--
1931include::../api/flags/VkFenceImportFlags.txt[]
1932
1933ifdef::VK_KHR_external_fence[]
1934or the equivalent
1935
1936include::../api/flags/VkFenceImportFlagsKHR.txt[]
1937endif::VK_KHR_external_fence[]
1938
1939sname:VkFenceImportFlags is a bitmask type for setting a mask of zero or
1940more slink:VkFenceImportFlagBits.
1941--
1942
1943endif::VK_KHR_external_fence_win32,VK_KHR_external_fence_fd[]
1944endif::VK_VERSION_1_1,VK_KHR_external_fence[]
1945
1946
1947[[synchronization-semaphores]]
1948== Semaphores
1949
1950[open,refpage='VkSemaphore',desc='Opaque handle to a semaphore object',type='handles']
1951--
1952
1953Semaphores are a synchronization primitive that can: be used to insert a
1954dependency between batches submitted to queues.
1955Semaphores have two states - signaled and unsignaled.
1956The state of a semaphore can: be signaled after execution of a batch of
1957commands is completed.
1958A batch can: wait for a semaphore to become signaled before it begins
1959execution, and the semaphore is also unsignaled before the batch begins
1960execution.
1961
1962ifdef::VK_VERSION_1_1,VK_KHR_external_semaphore[]
1963[[synchronization-semaphores-payloads]]
1964As with most objects in Vulkan, semaphores are an interface to internal data
1965which is typically opaque to applications.
1966This internal data is referred to as a semaphore's _payload_.
1967
1968However, in order to enable communication with agents outside of the current
1969device, it is necessary to be able to export that payload to a commonly
1970understood format, and subsequently import from that format as well.
1971
1972The internal data of a semaphore may: include a reference to any resources
1973and pending work associated with signal or unsignal operations performed on
1974that semaphore object.
1975Mechanisms to import and export that internal data to and from semaphores
1976are provided <<VkExportSemaphoreCreateInfo, below>>.
1977These mechanisms indirectly enable applications to share semaphore state
1978between two or more semaphores and other synchronization primitives across
1979process and API boundaries.
1980
1981endif::VK_VERSION_1_1,VK_KHR_external_semaphore[]
1982
1983Semaphores are represented by sname:VkSemaphore handles:
1984
1985include::../api/handles/VkSemaphore.txt[]
1986
1987--
1988
1989[open,refpage='vkCreateSemaphore',desc='Create a new queue semaphore object',type='protos']
1990--
1991
1992To create a semaphore, call:
1993
1994include::../api/protos/vkCreateSemaphore.txt[]
1995
1996  * pname:device is the logical device that creates the semaphore.
1997  * pname:pCreateInfo is a pointer to an instance of the
1998    sname:VkSemaphoreCreateInfo structure which contains information about
1999    how the semaphore is to be created.
2000  * pname:pAllocator controls host memory allocation as described in the
2001    <<memory-allocation, Memory Allocation>> chapter.
2002  * pname:pSemaphore points to a handle in which the resulting semaphore
2003    object is returned.
2004
2005When created, the semaphore is in the unsignaled state.
2006
2007include::../validity/protos/vkCreateSemaphore.txt[]
2008--
2009
2010[open,refpage='VkSemaphoreCreateInfo',desc='Structure specifying parameters of a newly created semaphore',type='structs']
2011--
2012
2013The sname:VkSemaphoreCreateInfo structure is defined as:
2014
2015include::../api/structs/VkSemaphoreCreateInfo.txt[]
2016
2017  * pname:sType is the type of this structure.
2018  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
2019  * pname:flags is reserved for future use.
2020
2021include::../validity/structs/VkSemaphoreCreateInfo.txt[]
2022--
2023
2024[open,refpage='VkSemaphoreCreateFlags',desc='Reserved for future use',type='enums']
2025--
2026include::../api/flags/VkSemaphoreCreateFlags.txt[]
2027
2028sname:VkSemaphoreCreateFlags is a bitmask type for setting a mask, but is
2029currently reserved for future use.
2030--
2031
2032ifdef::VK_VERSION_1_1,VK_KHR_external_semaphore[]
2033
2034[open,refpage='VkExportSemaphoreCreateInfo',desc='Structure specifying handle types that can be exported from a semaphore',type='structs']
2035--
2036
2037To create a semaphore whose payload can: be exported to external handles,
2038add the slink:VkExportSemaphoreCreateInfo structure to the pname:pNext chain
2039of the slink:VkSemaphoreCreateInfo structure.
2040The sname:VkExportSemaphoreCreateInfo structure is defined as:
2041
2042include::../api/structs/VkExportSemaphoreCreateInfo.txt[]
2043
2044ifdef::VK_KHR_external_semaphore[]
2045or the equivalent
2046
2047include::../api/structs/VkExportSemaphoreCreateInfoKHR.txt[]
2048endif::VK_KHR_external_semaphore[]
2049
2050  * pname:sType is the type of this structure.
2051  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
2052  * pname:handleTypes is a bitmask of
2053    elink:VkExternalSemaphoreHandleTypeFlagBits specifying one or more
2054    semaphore handle types the application can: export from the resulting
2055    semaphore.
2056    The application can: request multiple handle types for the same
2057    semaphore.
2058
2059.Valid Usage
2060****
2061  * [[VUID-VkExportSemaphoreCreateInfo-handleTypes-01124]]
2062    The bits in pname:handleTypes must: be supported and compatible, as
2063    reported by slink:VkExternalSemaphoreProperties.
2064****
2065
2066include::../validity/structs/VkExportSemaphoreCreateInfo.txt[]
2067--
2068
2069endif::VK_VERSION_1_1,VK_KHR_external_semaphore[]
2070
2071ifdef::VK_KHR_external_semaphore_win32[]
2072
2073[open,refpage='VkExportSemaphoreWin32HandleInfoKHR',desc='Structure specifying additional attributes of Windows handles exported from a semaphore',type='structs']
2074--
2075
2076To specify additional attributes of NT handles exported from a semaphore,
2077add the sname:VkExportSemaphoreWin32HandleInfoKHR structure to the
2078pname:pNext chain of the slink:VkSemaphoreCreateInfo structure.
2079The sname:VkExportSemaphoreWin32HandleInfoKHR structure is defined as:
2080
2081include::../api/structs/VkExportSemaphoreWin32HandleInfoKHR.txt[]
2082
2083  * pname:sType is the type of this structure.
2084  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
2085  * pname:pAttributes is a pointer to a Windows code:SECURITY_ATTRIBUTES
2086    structure specifying security attributes of the handle.
2087  * pname:dwAccess is a code:DWORD specifying access rights of the handle.
2088  * pname:name is a NULL-terminated UTF-16 string to associate with the
2089    underlying synchronization primitive referenced by NT handles exported
2090    from the created semaphore.
2091
2092If this structure is not present, or if pname:pAttributes is set to `NULL`,
2093default security descriptor values will be used, and child processes created
2094by the application will not inherit the handle, as described in the MSDN
2095documentation for "`Synchronization Object Security and Access Rights`"^1^.
2096Further, if the structure is not present, the access rights will be
2097
2098code:DXGI_SHARED_RESOURCE_READ | code:DXGI_SHARED_RESOURCE_WRITE
2099
2100for handles of the following types:
2101
2102ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
2103
2104And
2105
2106code:GENERIC_ALL
2107
2108for handles of the following types:
2109
2110ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT
2111
21121::
2113    https://msdn.microsoft.com/en-us/library/windows/desktop/ms686670.aspx
2114
2115.Valid Usage
2116****
2117  * [[VUID-VkExportSemaphoreWin32HandleInfoKHR-handleTypes-01125]]
2118    If slink:VkExportSemaphoreCreateInfo::pname:handleTypes does not include
2119    ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT or
2120    ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT,
2121    sname:VkExportSemaphoreWin32HandleInfoKHR must: not be in the
2122    pname:pNext chain of slink:VkSemaphoreCreateInfo.
2123****
2124
2125include::../validity/structs/VkExportSemaphoreWin32HandleInfoKHR.txt[]
2126--
2127
2128[open,refpage='vkGetSemaphoreWin32HandleKHR',desc='Get a Windows HANDLE for a semaphore',type='protos']
2129--
2130
2131To export a Windows handle representing the payload of a semaphore, call:
2132
2133include::../api/protos/vkGetSemaphoreWin32HandleKHR.txt[]
2134
2135  * pname:device is the logical device that created the semaphore being
2136    exported.
2137  * pname:pGetWin32HandleInfo is a pointer to an instance of the
2138    slink:VkSemaphoreGetWin32HandleInfoKHR structure containing parameters
2139    of the export operation.
2140  * pname:pHandle will return the Windows handle representing the semaphore
2141    state.
2142
2143For handle types defined as NT handles, the handles returned by
2144fname:vkGetSemaphoreWin32HandleKHR are owned by the application.
2145To avoid leaking resources, the application must: release ownership of them
2146using the fname:CloseHandle system call when they are no longer needed.
2147
2148Exporting a Windows handle from a semaphore may: have side effects depending
2149on the transference of the specified handle type, as described in
2150<<synchronization-semaphores-importing,Importing Semaphore Payloads>>.
2151
2152include::../validity/protos/vkGetSemaphoreWin32HandleKHR.txt[]
2153--
2154
2155[open,refpage='VkSemaphoreGetWin32HandleInfoKHR',desc='Structure describing a Win32 handle semaphore export operation',type='structs']
2156--
2157
2158The sname:VkSemaphoreGetWin32HandleInfoKHR structure is defined as:
2159
2160include::../api/structs/VkSemaphoreGetWin32HandleInfoKHR.txt[]
2161
2162  * pname:sType is the type of this structure.
2163  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
2164  * pname:semaphore is the semaphore from which state will be exported.
2165  * pname:handleType is the type of handle requested.
2166
2167The properties of the handle returned depend on the value of
2168pname:handleType.
2169See elink:VkExternalSemaphoreHandleTypeFlagBits for a description of the
2170properties of the defined external semaphore handle types.
2171
2172.Valid Usage
2173****
2174  * [[VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01126]]
2175    pname:handleType must: have been included in
2176    slink:VkExportSemaphoreCreateInfo::pname:handleTypes when the
2177    pname:semaphore's current payload was created.
2178  * [[VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01127]]
2179    If pname:handleType is defined as an NT handle,
2180    flink:vkGetSemaphoreWin32HandleKHR must: be called no more than once for
2181    each valid unique combination of pname:semaphore and pname:handleType.
2182  * [[VUID-VkSemaphoreGetWin32HandleInfoKHR-semaphore-01128]]
2183    pname:semaphore must: not currently have its payload replaced by an
2184    imported payload as described below in
2185    <<synchronization-semaphores-importing,Importing Semaphore Payloads>>
2186    unless that imported payload's handle type was included in
2187    slink:VkExternalSemaphoreProperties::pname:exportFromImportedHandleTypes
2188    for pname:handleType.
2189  * [[VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01129]]
2190    If pname:handleType refers to a handle type with copy payload
2191    transference semantics, as defined below in
2192    <<synchronization-semaphores-importing,Importing Semaphore Payloads>>,
2193    there must: be no queue waiting on pname:semaphore.
2194  * [[VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01130]]
2195    If pname:handleType refers to a handle type with copy payload
2196    transference semantics, pname:semaphore must: be signaled, or have an
2197    associated <<synchronization-semaphores-signaling,semaphore signal
2198    operation>> pending execution.
2199  * [[VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01131]]
2200    pname:handleType must: be defined as an NT handle or a global share
2201    handle.
2202****
2203
2204include::../validity/structs/VkSemaphoreGetWin32HandleInfoKHR.txt[]
2205--
2206
2207endif::VK_KHR_external_semaphore_win32[]
2208
2209ifdef::VK_KHR_external_semaphore_fd[]
2210
2211[open,refpage='vkGetSemaphoreFdKHR',desc='Get a POSIX file descriptor handle for a semaphore',type='protos']
2212--
2213
2214To export a POSIX file descriptor representing the payload of a semaphore,
2215call:
2216
2217include::../api/protos/vkGetSemaphoreFdKHR.txt[]
2218
2219  * pname:device is the logical device that created the semaphore being
2220    exported.
2221  * pname:pGetFdInfo is a pointer to an instance of the
2222    slink:VkSemaphoreGetFdInfoKHR structure containing parameters of the
2223    export operation.
2224  * pname:pFd will return the file descriptor representing the semaphore
2225    payload.
2226
2227Each call to fname:vkGetSemaphoreFdKHR must: create a new file descriptor
2228and transfer ownership of it to the application.
2229To avoid leaking resources, the application must: release ownership of the
2230file descriptor when it is no longer needed.
2231
2232[NOTE]
2233.Note
2234====
2235Ownership can be released in many ways.
2236For example, the application can call code:close() on the file descriptor,
2237or transfer ownership back to Vulkan by using the file descriptor to import
2238a semaphore payload.
2239====
2240Where supported by the operating system, the implementation must: set the
2241file descriptor to be closed automatically when an code:execve system call
2242is made.
2243
2244Exporting a file descriptor from a semaphore may: have side effects
2245depending on the transference of the specified handle type, as described in
2246<<synchronization-semaphores-importing,Importing Semaphore State>>.
2247
2248include::../validity/protos/vkGetSemaphoreFdKHR.txt[]
2249--
2250
2251[open,refpage='VkSemaphoreGetFdInfoKHR',desc='Structure describing a POSIX FD semaphore export operation',type='structs']
2252--
2253
2254The sname:VkSemaphoreGetFdInfoKHR structure is defined as:
2255
2256include::../api/structs/VkSemaphoreGetFdInfoKHR.txt[]
2257
2258  * pname:sType is the type of this structure.
2259  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
2260  * pname:semaphore is the semaphore from which state will be exported.
2261  * pname:handleType is the type of handle requested.
2262
2263The properties of the file descriptor returned depend on the value of
2264pname:handleType.
2265See elink:VkExternalSemaphoreHandleTypeFlagBits for a description of the
2266properties of the defined external semaphore handle types.
2267
2268.Valid Usage
2269****
2270  * [[VUID-VkSemaphoreGetFdInfoKHR-handleType-01132]]
2271    pname:handleType must: have been included in
2272    slink:VkExportSemaphoreCreateInfo::pname:handleTypes when
2273    pname:semaphore's current payload was created.
2274  * [[VUID-VkSemaphoreGetFdInfoKHR-semaphore-01133]]
2275    pname:semaphore must: not currently have its payload replaced by an
2276    imported payload as described below in
2277    <<synchronization-semaphores-importing,Importing Semaphore Payloads>>
2278    unless that imported payload's handle type was included in
2279    slink:VkExternalSemaphoreProperties::pname:exportFromImportedHandleTypes
2280    for pname:handleType.
2281  * [[VUID-VkSemaphoreGetFdInfoKHR-handleType-01134]]
2282    If pname:handleType refers to a handle type with copy payload
2283    transference semantics, as defined below in
2284    <<synchronization-semaphores-importing,Importing Semaphore Payloads>>,
2285    there must: be no queue waiting on pname:semaphore.
2286  * [[VUID-VkSemaphoreGetFdInfoKHR-handleType-01135]]
2287    If pname:handleType refers to a handle type with copy payload
2288    transference semantics, pname:semaphore must: be signaled, or have an
2289    associated <<synchronization-semaphores-signaling,semaphore signal
2290    operation>> pending execution.
2291  * [[VUID-VkSemaphoreGetFdInfoKHR-handleType-01136]]
2292    pname:handleType must: be defined as a POSIX file descriptor handle.
2293****
2294
2295include::../validity/structs/VkSemaphoreGetFdInfoKHR.txt[]
2296--
2297
2298endif::VK_KHR_external_semaphore_fd[]
2299
2300[open,refpage='vkDestroySemaphore',desc='Destroy a semaphore object',type='protos']
2301--
2302
2303To destroy a semaphore, call:
2304
2305include::../api/protos/vkDestroySemaphore.txt[]
2306
2307  * pname:device is the logical device that destroys the semaphore.
2308  * pname:semaphore is the handle of the semaphore to destroy.
2309  * pname:pAllocator controls host memory allocation as described in the
2310    <<memory-allocation, Memory Allocation>> chapter.
2311
2312.Valid Usage
2313****
2314  * [[VUID-vkDestroySemaphore-semaphore-01137]]
2315    All submitted batches that refer to pname:semaphore must: have completed
2316    execution
2317  * [[VUID-vkDestroySemaphore-semaphore-01138]]
2318    If sname:VkAllocationCallbacks were provided when pname:semaphore was
2319    created, a compatible set of callbacks must: be provided here
2320  * [[VUID-vkDestroySemaphore-semaphore-01139]]
2321    If no sname:VkAllocationCallbacks were provided when pname:semaphore was
2322    created, pname:pAllocator must: be `NULL`
2323****
2324
2325include::../validity/protos/vkDestroySemaphore.txt[]
2326--
2327
2328
2329[[synchronization-semaphores-signaling]]
2330=== Semaphore Signaling
2331
2332When a batch is submitted to a queue via a <<devsandqueues-submission, queue
2333submission>>, and it includes semaphores to be signaled, it defines a memory
2334dependency on the batch, and defines _semaphore signal operations_ which set
2335the semaphores to the signaled state.
2336
2337The first <<synchronization-dependencies-scopes, synchronization scope>>
2338includes every command submitted in the same batch.
2339Semaphore signal operations that are defined by flink:vkQueueSubmit
2340additionally include all commands that occur earlier in
2341<<synchronization-submission-order,submission order>>.
2342
2343The second <<synchronization-dependencies-scopes, synchronization scope>>
2344includes only the semaphore signal operation.
2345
2346The first <<synchronization-dependencies-access-scopes, access scope>>
2347includes all memory access performed by the device.
2348
2349The second <<synchronization-dependencies-access-scopes, access scope>> is
2350empty.
2351
2352
2353[[synchronization-semaphores-waiting]]
2354=== Semaphore Waiting & Unsignaling
2355
2356When a batch is submitted to a queue via a <<devsandqueues-submission, queue
2357submission>>, and it includes semaphores to be waited on, it defines a
2358memory dependency between prior semaphore signal operations and the batch,
2359and defines _semaphore unsignal operations_ which set the semaphores to the
2360unsignaled state.
2361
2362The first synchronization scope includes all semaphore signal operations
2363that operate on semaphores waited on in the same batch, and that
2364happen-before the wait completes.
2365
2366The second <<synchronization-dependencies-scopes, synchronization scope>>
2367includes every command submitted in the same batch.
2368In the case of flink:vkQueueSubmit, the second synchronization scope is
2369limited to operations on the pipeline stages determined by the
2370<<synchronization-pipeline-stages-masks, destination stage mask>> specified
2371by the corresponding element of pname:pWaitDstStageMask.
2372Also, in the case of flink:vkQueueSubmit, the second synchronization scope
2373additionally includes all commands that occur later in
2374<<synchronization-submission-order,submission order>>.
2375
2376The first <<synchronization-dependencies-access-scopes, access scope>> is
2377empty.
2378
2379The second <<synchronization-dependencies-access-scopes, access scope>>
2380includes all memory access performed by the device.
2381
2382The semaphore unsignal operation happens-after the first set of operations
2383in the execution dependency, and happens-before the second set of operations
2384in the execution dependency.
2385
2386[NOTE]
2387.Note
2388====
2389Unlike fences or events, the act of waiting for a semaphore also unsignals
2390that semaphore.
2391If two operations are separately specified to wait for the same semaphore,
2392and there are no other execution dependencies between those operations,
2393behaviour is undefined.
2394An execution dependency must: be present that guarantees that the semaphore
2395unsignal operation for the first of those waits, happens-before the
2396semaphore is signalled again, and before the second unsignal operation.
2397Semaphore waits and signals should thus occur in discrete 1:1 pairs.
2398====
2399
2400ifdef::VK_KHR_swapchain[]
2401[NOTE]
2402.Note
2403====
2404A common scenario for using pname:pWaitDstStageMask with values other than
2405ename:VK_PIPELINE_STAGE_ALL_COMMANDS_BIT is when synchronizing a window
2406system presentation operation against subsequent command buffers which
2407render the next frame.
2408In this case, a presentation image must: not be overwritten until the
2409presentation operation completes, but other pipeline stages can: execute
2410without waiting.
2411A mask of ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT prevents
2412subsequent color attachment writes from executing until the semaphore
2413signals.
2414Some implementations may: be able to execute transfer operations and/or
2415vertex processing work before the semaphore is signaled.
2416
2417If an image layout transition needs to be performed on a presentable image
2418before it is used in a framebuffer, that can: be performed as the first
2419operation submitted to the queue after acquiring the image, and should: not
2420prevent other work from overlapping with the presentation operation.
2421For example, a sname:VkImageMemoryBarrier could use:
2422
2423  * pname:srcStageMask = ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
2424  * pname:srcAccessMask = 0
2425  * pname:dstStageMask = ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
2426  * pname:dstAccessMask = ename:VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
2427    ename:VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT.
2428  * pname:oldLayout = ename:VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
2429  * pname:newLayout = ename:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
2430
2431Alternatively, pname:oldLayout can: be ename:VK_IMAGE_LAYOUT_UNDEFINED, if
2432the image's contents need not be preserved.
2433
2434This barrier accomplishes a dependency chain between previous presentation
2435operations and subsequent color attachment output operations, with the
2436layout transition performed in between, and does not introduce a dependency
2437between previous work and any vertex processing stages.
2438More precisely, the semaphore signals after the presentation operation
2439completes, the semaphore wait stalls the
2440ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT stage, and there is a
2441dependency from that same stage to itself with the layout transition
2442performed in between.
2443====
2444endif::VK_KHR_swapchain[]
2445
2446
2447[[synchronization-semaphores-waiting-state]]
2448=== Semaphore State Requirements For Wait Operations
2449
2450Before waiting on a semaphore, the application must: ensure the semaphore is
2451in a valid state for a wait operation.
2452Specifically, when a <<synchronization-semaphores-waiting,semaphore wait and
2453unsignal operation>> is submitted to a queue:
2454
2455  * The semaphore must: be signaled, or have an associated
2456    <<synchronization-semaphores-signaling,semaphore signal operation>> that
2457    is pending execution.
2458  * There must: be no other queue waiting on the same semaphore when the
2459    operation executes.
2460
2461ifdef::VK_VERSION_1_1,VK_KHR_external_semaphore[]
2462
2463[[synchronization-semaphores-importing]]
2464=== Importing Semaphore Payloads
2465
2466Applications can: import a semaphore payload into an existing semaphore
2467using an external semaphore handle.
2468The effects of the import operation will be either temporary or permanent,
2469as specified by the application.
2470If the import is temporary, the implementation must: restore the semaphore
2471to its prior permanent state after submitting the next semaphore wait
2472operation.
2473Performing a subsequent temporary import on a semaphore before performing a
2474semaphore wait has no effect on this requirement; the next wait submitted on
2475the semaphore must: still restore its last permanent state.
2476A permanent payload import behaves as if the target semaphore was destroyed,
2477and a new semaphore was created with the same handle but the imported
2478payload.
2479Because importing a semaphore payload temporarily or permanently detaches
2480the existing payload from a semaphore, similar usage restrictions to those
2481applied to fname:vkDestroySemaphore are applied to any command that imports
2482a semaphore payload.
2483Which of these import types is used is referred to as the import operation's
2484_permanence_.
2485Each handle type supports either one or both types of permanence.
2486
2487The implementation must: perform the import operation by either referencing
2488or copying the payload referred to by the specified external semaphore
2489handle, depending on the handle's type.
2490The import method used is referred to as the handle type's _transference_.
2491When using handle types with reference transference, importing a payload to
2492a semaphore adds the semaphore to the set of all semaphores sharing that
2493payload.
2494This set includes the semaphore from which the payload was exported.
2495Semaphore signaling and waiting operations performed on any semaphore in the
2496set must: behave as if the set were a single semaphore.
2497Importing a payload using handle types with copy transference creates a
2498duplicate copy of the payload at the time of import, but makes no further
2499reference to it.
2500Semaphore signaling and waiting operations performed on the target of copy
2501imports must: not affect any other semaphore or payload.
2502
2503Export operations have the same transference as the specified handle type's
2504import operations.
2505Additionally, exporting a semaphore payload to a handle with copy
2506transference has the same side effects on the source semaphore's payload as
2507executing a semaphore wait operation.
2508If the semaphore was using a temporarily imported payload, the semaphore's
2509prior permanent payload will be restored.
2510
2511ifdef::VK_KHR_external_semaphore_win32,VK_KHR_external_semaphore_fd[]
2512[NOTE]
2513.Note
2514====
2515The
2516ifdef::VK_KHR_external_semaphore_win32+VK_KHR_external_semaphore_fd[tables]
2517ifndef::VK_KHR_external_semaphore_win32+VK_KHR_external_semaphore_fd[table]
2518ifdef::VK_KHR_external_semaphore_win32[]
2519<<synchronization-semaphore-handletypes-win32,Handle Types Supported by
2520VkImportSemaphoreWin32HandleInfoKHR>>
2521endif::VK_KHR_external_semaphore_win32[]
2522ifdef::VK_KHR_external_semaphore_win32+VK_KHR_external_semaphore_fd[and]
2523ifdef::VK_KHR_external_semaphore_fd[]
2524<<synchronization-semaphore-handletypes-fd,Handle Types Supported by
2525VkImportSemaphoreFdInfoKHR>>
2526endif::VK_KHR_external_semaphore_fd[]
2527ifdef::VK_KHR_external_semaphore_win32+VK_KHR_external_semaphore_fd[define]
2528ifndef::VK_KHR_external_semaphore_win32+VK_KHR_external_semaphore_fd[defines]
2529the permanence and transference of each handle type.
2530====
2531endif::VK_KHR_external_semaphore_win32,VK_KHR_external_semaphore_fd[]
2532
2533<<fundamentals-threadingbehavior,External synchronization>> allows
2534implementations to modify an object's internal state, i.e. payload, without
2535internal synchronization.
2536However, for semaphores sharing a payload across processes, satisfying the
2537external synchronization requirements of fname:VkSemaphore parameters as if
2538all semaphores in the set were the same object is sometimes infeasible.
2539Satisfying the <<synchronization-semaphores-waiting-state,wait operation
2540state requirements>> would similarly require impractical coordination or
2541levels of trust between processes.
2542Therefore, these constraints only apply to a specific semaphore handle, not
2543to its payload.
2544For distinct semaphore objects which share a payload, if the semaphores are
2545passed to separate queue submission commands concurrently, behavior will be
2546as if the commands were called in an arbitrary sequential order.
2547If the <<synchronization-semaphores-waiting-state,wait operation state
2548requirements>> are violated for the shared payload by a queue submission
2549command, or if a signal operation is queued for a shared payload that is
2550already signaled or has a pending signal operation, effects must: be limited
2551to one or more of the following:
2552
2553  * Returning ename:VK_ERROR_INITIALIZATION_FAILED from the command which
2554    resulted in the violation.
2555  * Losing the logical device on which the violation occured immediately or
2556    at a future time, resulting in a ename:VK_ERROR_DEVICE_LOST error from
2557    subsequent commands, including the one causing the violation.
2558  * Continuing execution of the violating command or operation as if the
2559    semaphore wait completed successfully after an implementation-dependent
2560    timeout.
2561    In this case, the state of the payload becomes undefined, and future
2562    operations on semaphores sharing the payload will be subject to these
2563    same rules.
2564    The semaphore must: be destroyed or have its payload replaced by an
2565    import operation to again have a well-defined state.
2566
2567[NOTE]
2568.Note
2569====
2570These rules allow processes to synchronize access to shared memory without
2571trusting each other.
2572However, such processes must still be cautious not to use the shared
2573semaphore for more than synchronizing access to the shared memory.
2574For example, a process should not use a shared semaphore as part of an
2575execution dependency chain that, when complete, leads to objects being
2576destroyed, if it does not trust other processes sharing the semaphore
2577payload.
2578====
2579
2580When a semaphore is using an imported payload, its
2581slink:VkExportSemaphoreCreateInfo::pname:handleTypes value is that specified
2582when creating the semaphore from which the payload was exported, rather than
2583that specified when creating the semaphore.
2584Additionally,
2585slink:VkExternalSemaphoreProperties::exportFromImportedHandleTypes restricts
2586which handle types can: be exported from such a semaphore based on the
2587specific handle type used to import the current payload.
2588ifdef::VK_KHR_swapchain[]
2589Passing a semaphore to flink:vkAcquireNextImageKHR is equivalent to
2590temporarily importing a semaphore payload to that semaphore.
2591
2592[NOTE]
2593.Note
2594====
2595Because the exportable handle types of an imported semaphore correspond to
2596its current imported payload, and flink:vkAcquireNextImageKHR behaves the
2597same as a temporary import operation for which the source semaphore is
2598opaque to the application, applications have no way of determining whether
2599any external handle types can: be exported from a semaphore in this state.
2600Therefore, applications must: not attempt to export external handles from
2601semaphores using a temporarily imported payload from
2602flink:vkAcquireNextImageKHR.
2603====
2604endif::VK_KHR_swapchain[]
2605
2606When importing a semaphore payload, it is the responsibility of the
2607application to ensure the external handles meet all valid usage
2608requirements.
2609However, implementations must: perform sufficient validation of external
2610handles to ensure that the operation results in a valid semaphore which will
2611not cause program termination, device loss, queue stalls, or corruption of
2612other resources when used as allowed according to its import parameters, and
2613excepting those side effects allowed for violations of the
2614<<synchronization-semaphores-waiting-state,valid semaphore state for wait
2615operations>> rules.
2616If the external handle provided does not meet these requirements, the
2617implementation must: fail the semaphore payload import operation with the
2618error code ename:VK_ERROR_INVALID_EXTERNAL_HANDLE.
2619
2620endif::VK_VERSION_1_1,VK_KHR_external_semaphore[]
2621
2622ifdef::VK_KHR_external_semaphore_win32[]
2623
2624[open,refpage='vkImportSemaphoreWin32HandleKHR',desc='Import a semaphore from a Windows HANDLE',type='protos']
2625--
2626
2627To import a semaphore payload from a Windows handle, call:
2628
2629include::../api/protos/vkImportSemaphoreWin32HandleKHR.txt[]
2630
2631  * pname:device is the logical device that created the semaphore.
2632  * pname:pImportSemaphoreWin32HandleInfo points to a
2633    slink:VkImportSemaphoreWin32HandleInfoKHR structure specifying the
2634    semaphore and import parameters.
2635
2636Importing a semaphore payload from Windows handles does not transfer
2637ownership of the handle to the Vulkan implementation.
2638For handle types defined as NT handles, the application must: release
2639ownership using the fname:CloseHandle system call when the handle is no
2640longer needed.
2641
2642Applications can: import the same semaphore payload into multiple instances
2643of Vulkan, into the same instance from which it was exported, and multiple
2644times into a given Vulkan instance.
2645
2646include::../validity/protos/vkImportSemaphoreWin32HandleKHR.txt[]
2647--
2648
2649[open,refpage='VkImportSemaphoreWin32HandleInfoKHR',desc='Structure specifying Windows handle to import to a semaphore',type='structs']
2650--
2651
2652The sname:VkImportSemaphoreWin32HandleInfoKHR structure is defined as:
2653
2654include::../api/structs/VkImportSemaphoreWin32HandleInfoKHR.txt[]
2655
2656  * pname:sType is the type of this structure.
2657  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
2658  * pname:semaphore is the semaphore into which the payload will be
2659    imported.
2660  * pname:flags is a bitmask of elink:VkSemaphoreImportFlagBits specifying
2661    additional parameters for the semaphore payload import operation.
2662  * pname:handleType specifies the type of pname:handle.
2663  * pname:handle is the external handle to import, or `NULL`.
2664  * pname:name is a NULL-terminated UTF-16 string naming the underlying
2665    synchronization primitive to import, or `NULL`.
2666
2667The handle types supported by pname:handleType are:
2668
2669[[synchronization-semaphore-handletypes-win32]]
2670.Handle Types Supported by VkImportSemaphoreWin32HandleInfoKHR
2671[width="80%",options="header"]
2672|====
2673| Handle Type                                                      | Transference | Permanence Supported
2674| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT     | Reference    | Temporary,Permanent
2675| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT | Reference    | Temporary,Permanent
2676| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT      | Reference    | Temporary,Permanent
2677|====
2678
2679.Valid Usage
2680****
2681  * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handleType-01140]]
2682    pname:handleType must: be a value included in the
2683    <<synchronization-semaphore-handletypes-win32,Handle Types Supported by
2684    VkImportSemaphoreWin32HandleInfoKHR>> table.
2685  * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handleType-01466]]
2686    If pname:handleType is not
2687    ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT or
2688    ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, pname:name
2689    must: be `NULL`.
2690  * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handleType-01467]]
2691    If pname:handleType is not `0` and pname:handle is `NULL`, pname:name
2692    must: name a valid synchronization primitive of the type specified by
2693    pname:handleType.
2694  * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handleType-01468]]
2695    If pname:handleType is not `0` and pname:name is `NULL`, pname:handle
2696    must: be a valid handle of the type specified by pname:handleType.
2697  * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handle-01469]]
2698    If pname:handle is not `NULL`, pname:name must be `NULL`.
2699  * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handle-01542]]
2700    If pname:handle is not `NULL`, it must: obey any requirements listed for
2701    pname:handleType in
2702    <<external-semaphore-handle-types-compatibility,external semaphore
2703    handle types compatibility>>.
2704  * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-name-01543]]
2705    If pname:name is not `NULL`, it must: obey any requirements listed for
2706    pname:handleType in
2707    <<external-semaphore-handle-types-compatibility,external semaphore
2708    handle types compatibility>>.
2709****
2710
2711include::../validity/structs/VkImportSemaphoreWin32HandleInfoKHR.txt[]
2712--
2713
2714endif::VK_KHR_external_semaphore_win32[]
2715
2716ifdef::VK_KHR_external_semaphore_fd[]
2717
2718[open,refpage='vkImportSemaphoreFdKHR',desc='Import a semaphore from a POSIX file descriptor',type='protos']
2719--
2720
2721To import a semaphore payload from a POSIX file descriptor, call:
2722
2723include::../api/protos/vkImportSemaphoreFdKHR.txt[]
2724
2725  * pname:device is the logical device that created the semaphore.
2726  * pname:pImportSemaphoreFdInfo points to a
2727    slink:VkImportSemaphoreFdInfoKHR structure specifying the semaphore and
2728    import parameters.
2729
2730Importing a semaphore payload from a file descriptor transfers ownership of
2731the file descriptor from the application to the Vulkan implementation.
2732The application must: not perform any operations on the file descriptor
2733after a successful import.
2734
2735Applications can: import the same semaphore payload into multiple instances
2736of Vulkan, into the same instance from which it was exported, and multiple
2737times into a given Vulkan instance.
2738
2739.Valid Usage
2740****
2741  * [[VUID-vkImportSemaphoreFdKHR-semaphore-01142]]
2742    pname:semaphore must: not be associated with any queue command that has
2743    not yet completed execution on that queue
2744****
2745
2746include::../validity/protos/vkImportSemaphoreFdKHR.txt[]
2747--
2748
2749[open,refpage='VkImportSemaphoreFdInfoKHR',desc='Structure specifying POSIX file descriptor to import to a semaphore',type='structs']
2750--
2751
2752The sname:VkImportSemaphoreFdInfoKHR structure is defined as:
2753
2754include::../api/structs/VkImportSemaphoreFdInfoKHR.txt[]
2755
2756  * pname:sType is the type of this structure.
2757  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
2758  * pname:semaphore is the semaphore into which the payload will be
2759    imported.
2760  * pname:flags is a bitmask of elink:VkSemaphoreImportFlagBits specifying
2761    additional parameters for the semaphore payload import operation.
2762  * pname:handleType specifies the type of pname:fd.
2763  * pname:fd is the external handle to import.
2764
2765The handle types supported by pname:handleType are:
2766
2767[[synchronization-semaphore-handletypes-fd]]
2768.Handle Types Supported by VkImportSemaphoreFdInfoKHR
2769[width="80%",options="header"]
2770|====
2771| Handle Type                                               | Transference | Permanence Supported
2772| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT | Reference    | Temporary,Permanent
2773| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT   | Copy         | Temporary
2774|====
2775
2776.Valid Usage
2777****
2778  * [[VUID-VkImportSemaphoreFdInfoKHR-handleType-01143]]
2779    pname:handleType must: be a value included in the
2780    <<synchronization-semaphore-handletypes-fd,Handle Types Supported by
2781    VkImportSemaphoreFdInfoKHR>> table.
2782  * [[VUID-VkImportSemaphoreFdInfoKHR-fd-01544]]
2783    pname:fd must: obey any requirements listed for pname:handleType in
2784    <<external-semaphore-handle-types-compatibility,external semaphore
2785    handle types compatibility>>.
2786****
2787
2788include::../validity/structs/VkImportSemaphoreFdInfoKHR.txt[]
2789--
2790
2791endif::VK_KHR_external_semaphore_fd[]
2792
2793ifdef::VK_VERSION_1_1,VK_KHR_external_semaphore[]
2794ifdef::VK_KHR_external_semaphore_win32,VK_KHR_external_semaphore_fd[]
2795
2796[open,refpage='VkSemaphoreImportFlagBits',desc='Bitmask specifying additional parameters of semaphore payload import',type='enums']
2797--
2798
2799Additional parameters of a semaphore import operation are specified by
2800ifdef::VK_KHR_external_semaphore_win32[]
2801slink:VkImportSemaphoreWin32HandleInfoKHR::pname:flags
2802endif::VK_KHR_external_semaphore_win32[]
2803ifdef::VK_KHR_external_semaphore_win32+VK_KHR_external_semaphore_fd[or]
2804ifdef::VK_KHR_external_semaphore_fd[]
2805slink:VkImportSemaphoreFdInfoKHR::pname:flags
2806endif::VK_KHR_external_semaphore_fd[]
2807.
2808Bits which can be set include:
2809
2810include::../api/enums/VkSemaphoreImportFlagBits.txt[]
2811
2812ifdef::VK_KHR_external_semaphore[]
2813or the equivalent
2814
2815include::../api/enums/VkSemaphoreImportFlagBitsKHR.txt[]
2816endif::VK_KHR_external_semaphore[]
2817
2818These bits have the following meanings:
2819
2820  * ename:VK_SEMAPHORE_IMPORT_TEMPORARY_BIT specifies that the semaphore
2821    payload will be imported only temporarily, as described in
2822    <<synchronization-semaphores-importing,Importing Semaphore Payloads>>,
2823    regardless of the permanence of pname:handleType.
2824
2825--
2826
2827[open,refpage='VkSemaphoreImportFlags',desc='Bitmask of VkSemaphoreImportFlagBits',type='enums']
2828--
2829include::../api/flags/VkSemaphoreImportFlags.txt[]
2830
2831ifdef::VK_KHR_external_semaphore[]
2832or the equivalent
2833
2834include::../api/flags/VkSemaphoreImportFlagsKHR.txt[]
2835endif::VK_KHR_external_semaphore[]
2836
2837sname:VkSemaphoreImportFlags is a bitmask type for setting a mask of zero or
2838more slink:VkSemaphoreImportFlagBits.
2839--
2840
2841endif::VK_KHR_external_semaphore_win32,VK_KHR_external_semaphore_fd[]
2842endif::VK_VERSION_1_1,VK_KHR_external_semaphore[]
2843
2844
2845[[synchronization-events]]
2846== Events
2847
2848[open,refpage='VkEvent',desc='Opaque handle to an event object',type='handles']
2849--
2850
2851Events are a synchronization primitive that can: be used to insert a
2852fine-grained dependency between commands submitted to the same queue, or
2853between the host and a queue.
2854Events must: not be used to insert a dependency between commands submitted
2855to different queues.
2856Events have two states - signaled and unsignaled.
2857An application can: signal an event, or unsignal it, on either the host or
2858the device.
2859A device can: wait for an event to become signaled before executing further
2860operations.
2861No command exists to wait for an event to become signaled on the host, but
2862the current state of an event can: be queried.
2863
2864Events are represented by sname:VkEvent handles:
2865
2866include::../api/handles/VkEvent.txt[]
2867
2868--
2869
2870[open,refpage='vkCreateEvent',desc='Create a new event object',type='protos']
2871--
2872
2873To create an event, call:
2874
2875include::../api/protos/vkCreateEvent.txt[]
2876
2877  * pname:device is the logical device that creates the event.
2878  * pname:pCreateInfo is a pointer to an instance of the
2879    sname:VkEventCreateInfo structure which contains information about how
2880    the event is to be created.
2881  * pname:pAllocator controls host memory allocation as described in the
2882    <<memory-allocation, Memory Allocation>> chapter.
2883  * pname:pEvent points to a handle in which the resulting event object is
2884    returned.
2885
2886When created, the event object is in the unsignaled state.
2887
2888include::../validity/protos/vkCreateEvent.txt[]
2889--
2890
2891[open,refpage='VkEventCreateInfo',desc='Structure specifying parameters of a newly created event',type='structs']
2892--
2893
2894The sname:VkEventCreateInfo structure is defined as:
2895
2896include::../api/structs/VkEventCreateInfo.txt[]
2897
2898  * pname:sType is the type of this structure.
2899  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
2900  * pname:flags is reserved for future use.
2901
2902include::../validity/structs/VkEventCreateInfo.txt[]
2903--
2904
2905[open,refpage='VkEventCreateFlags',desc='Reserved for future use',type='enums']
2906--
2907include::../api/flags/VkEventCreateFlags.txt[]
2908
2909sname:VkEventCreateFlags is a bitmask type for setting a mask, but is
2910currently reserved for future use.
2911--
2912
2913[open,refpage='vkDestroyEvent',desc='Destroy an event object',type='protos']
2914--
2915
2916To destroy an event, call:
2917
2918include::../api/protos/vkDestroyEvent.txt[]
2919
2920  * pname:device is the logical device that destroys the event.
2921  * pname:event is the handle of the event to destroy.
2922  * pname:pAllocator controls host memory allocation as described in the
2923    <<memory-allocation, Memory Allocation>> chapter.
2924
2925.Valid Usage
2926****
2927  * [[VUID-vkDestroyEvent-event-01145]]
2928    All submitted commands that refer to pname:event must: have completed
2929    execution
2930  * [[VUID-vkDestroyEvent-event-01146]]
2931    If sname:VkAllocationCallbacks were provided when pname:event was
2932    created, a compatible set of callbacks must: be provided here
2933  * [[VUID-vkDestroyEvent-event-01147]]
2934    If no sname:VkAllocationCallbacks were provided when pname:event was
2935    created, pname:pAllocator must: be `NULL`
2936****
2937
2938include::../validity/protos/vkDestroyEvent.txt[]
2939--
2940
2941[open,refpage='vkGetEventStatus',desc='Retrieve the status of an event object',type='protos']
2942--
2943
2944To query the state of an event from the host, call:
2945
2946include::../api/protos/vkGetEventStatus.txt[]
2947
2948  * pname:device is the logical device that owns the event.
2949  * pname:event is the handle of the event to query.
2950
2951Upon success, fname:vkGetEventStatus returns the state of the event object
2952with the following return codes:
2953
2954.Event Object Status Codes
2955[width="80%",options="header"]
2956|====
2957| Status | Meaning
2958| ename:VK_EVENT_SET | The event specified by pname:event is signaled.
2959| ename:VK_EVENT_RESET | The event specified by pname:event is unsignaled.
2960|====
2961
2962If a fname:vkCmdSetEvent or fname:vkCmdResetEvent command is in a command
2963buffer that is in the <<commandbuffers-lifecycle, pending state>>, then the
2964value returned by this command may: immediately be out of date.
2965
2966The state of an event can: be updated by the host.
2967The state of the event is immediately changed, and subsequent calls to
2968fname:vkGetEventStatus will return the new state.
2969If an event is already in the requested state, then updating it to the same
2970state has no effect.
2971
2972include::../validity/protos/vkGetEventStatus.txt[]
2973--
2974
2975[[synchronization-events-signaling-host]]
2976[open,refpage='vkSetEvent',desc='Set an event to signaled state',type='protos']
2977--
2978
2979To set the state of an event to signaled from the host, call:
2980
2981include::../api/protos/vkSetEvent.txt[]
2982
2983  * pname:device is the logical device that owns the event.
2984  * pname:event is the event to set.
2985
2986When flink:vkSetEvent is executed on the host, it defines an _event signal
2987operation_ which sets the event to the signaled state.
2988
2989If pname:event is already in the signaled state when flink:vkSetEvent is
2990executed, then flink:vkSetEvent has no effect, and no event signal operation
2991occurs.
2992
2993include::../validity/protos/vkSetEvent.txt[]
2994--
2995
2996[[synchronization-events-unsignaling-host]]
2997[open,refpage='vkResetEvent',desc='Reset an event to non-signaled state',type='protos']
2998--
2999
3000To set the state of an event to unsignaled from the host, call:
3001
3002include::../api/protos/vkResetEvent.txt[]
3003
3004  * pname:device is the logical device that owns the event.
3005  * pname:event is the event to reset.
3006
3007When flink:vkResetEvent is executed on the host, it defines an _event
3008unsignal operation_ which resets the event to the unsignaled state.
3009
3010If pname:event is already in the unsignaled state when flink:vkResetEvent is
3011executed, then flink:vkResetEvent has no effect, and no event unsignal
3012operation occurs.
3013
3014.Valid Usage
3015****
3016  * [[VUID-vkResetEvent-event-01148]]
3017    pname:event must: not be waited on by a fname:vkCmdWaitEvents command
3018    that is currently executing
3019****
3020
3021include::../validity/protos/vkResetEvent.txt[]
3022--
3023
3024
3025The state of an event can: also be updated on the device by commands
3026inserted in command buffers.
3027
3028[[synchronization-events-signaling-device]]
3029[open,refpage='vkCmdSetEvent',desc='Set an event object to signaled state',type='protos']
3030--
3031
3032To set the state of an event to signaled from a device, call:
3033
3034include::../api/protos/vkCmdSetEvent.txt[]
3035
3036  * pname:commandBuffer is the command buffer into which the command is
3037    recorded.
3038  * pname:event is the event that will be signaled.
3039  * pname:stageMask specifies the <<synchronization-pipeline-stages,source
3040    stage mask>> used to determine when the pname:event is signaled.
3041
3042When flink:vkCmdSetEvent is submitted to a queue, it defines an execution
3043dependency on commands that were submitted before it, and defines an event
3044signal operation which sets the event to the signaled state.
3045
3046The first <<synchronization-dependencies-scopes, synchronization scope>>
3047includes all commands that occur earlier in
3048<<synchronization-submission-order,submission order>>.
3049The synchronization scope is limited to operations on the pipeline stages
3050determined by the <<synchronization-pipeline-stages-masks, source stage
3051mask>> specified by pname:stageMask.
3052
3053The second <<synchronization-dependencies-scopes, synchronization scope>>
3054includes only the event signal operation.
3055
3056If pname:event is already in the signaled state when flink:vkCmdSetEvent is
3057executed on the device, then flink:vkCmdSetEvent has no effect, no event
3058signal operation occurs, and no execution dependency is generated.
3059
3060.Valid Usage
3061****
3062  * [[VUID-vkCmdSetEvent-stageMask-01149]]
3063    pname:stageMask must: not include ename:VK_PIPELINE_STAGE_HOST_BIT
3064  * [[VUID-vkCmdSetEvent-stageMask-01150]]
3065    If the <<features-features-geometryShader,geometry shaders>> feature is
3066    not enabled, pname:stageMask must: not contain
3067    ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
3068  * [[VUID-vkCmdSetEvent-stageMask-01151]]
3069    If the <<features-features-tessellationShader,tessellation shaders>>
3070    feature is not enabled, pname:stageMask must: not contain
3071    ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or
3072    ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
3073ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
3074  * [[VUID-vkCmdSetEvent-commandBuffer-01152]]
3075    pname:commandBuffer's current device mask must: include exactly one
3076    physical device.
3077endif::VK_VERSION_1_1,VK_KHR_device_group[]
3078****
3079
3080include::../validity/protos/vkCmdSetEvent.txt[]
3081--
3082
3083[[synchronization-events-unsignaling-device]]
3084[open,refpage='vkCmdResetEvent',desc='Reset an event object to non-signaled state',type='protos']
3085--
3086
3087To set the state of an event to unsignaled from a device, call:
3088
3089include::../api/protos/vkCmdResetEvent.txt[]
3090
3091  * pname:commandBuffer is the command buffer into which the command is
3092    recorded.
3093  * pname:event is the event that will be unsignaled.
3094  * pname:stageMask is a bitmask of elink:VkPipelineStageFlagBits specifying
3095    the <<synchronization-pipeline-stages, source stage mask>> used to
3096    determine when the pname:event is unsignaled.
3097
3098When flink:vkCmdResetEvent is submitted to a queue, it defines an execution
3099dependency on commands that were submitted before it, and defines an event
3100unsignal operation which resets the event to the unsignaled state.
3101
3102The first <<synchronization-dependencies-scopes, synchronization scope>>
3103includes all commands that occur earlier in
3104<<synchronization-submission-order,submission order>>.
3105The synchronization scope is limited to operations on the pipeline stages
3106determined by the <<synchronization-pipeline-stages-masks, source stage
3107mask>> specified by pname:stageMask.
3108
3109The second <<synchronization-dependencies-scopes, synchronization scope>>
3110includes only the event unsignal operation.
3111
3112If pname:event is already in the unsignaled state when flink:vkCmdResetEvent
3113is executed on the device, then flink:vkCmdResetEvent has no effect, no
3114event unsignal operation occurs, and no execution dependency is generated.
3115
3116.Valid Usage
3117****
3118  * [[VUID-vkCmdResetEvent-stageMask-01153]]
3119    pname:stageMask must: not include ename:VK_PIPELINE_STAGE_HOST_BIT
3120  * [[VUID-vkCmdResetEvent-stageMask-01154]]
3121    If the <<features-features-geometryShader,geometry shaders>> feature is
3122    not enabled, pname:stageMask must: not contain
3123    ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
3124  * [[VUID-vkCmdResetEvent-stageMask-01155]]
3125    If the <<features-features-tessellationShader,tessellation shaders>>
3126    feature is not enabled, pname:stageMask must: not contain
3127    ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or
3128    ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
3129  * [[VUID-vkCmdResetEvent-event-01156]]
3130    When this command executes, pname:event must: not be waited on by a
3131    fname:vkCmdWaitEvents command that is currently executing
3132ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
3133  * [[VUID-vkCmdResetEvent-commandBuffer-01157]]
3134    pname:commandBuffer's current device mask must: include exactly one
3135    physical device.
3136endif::VK_VERSION_1_1,VK_KHR_device_group[]
3137****
3138
3139include::../validity/protos/vkCmdResetEvent.txt[]
3140--
3141
3142[open,refpage='vkCmdWaitEvents',desc='Wait for one or more events and insert a set of memory',type='protos']
3143--
3144
3145To wait for one or more events to enter the signaled state on a device,
3146call:
3147
3148[[synchronization-events-waiting-device]]
3149include::../api/protos/vkCmdWaitEvents.txt[]
3150
3151  * pname:commandBuffer is the command buffer into which the command is
3152    recorded.
3153  * pname:eventCount is the length of the pname:pEvents array.
3154  * pname:pEvents is an array of event object handles to wait on.
3155  * pname:srcStageMask is a bitmask of elink:VkPipelineStageFlagBits
3156    specifying the <<synchronization-pipeline-stages, source stage mask>>.
3157  * pname:dstStageMask is a bitmask of elink:VkPipelineStageFlagBits
3158    specifying the <<synchronization-pipeline-stages, destination stage
3159    mask>>.
3160  * pname:memoryBarrierCount is the length of the pname:pMemoryBarriers
3161    array.
3162  * pname:pMemoryBarriers is a pointer to an array of slink:VkMemoryBarrier
3163    structures.
3164  * pname:bufferMemoryBarrierCount is the length of the
3165    pname:pBufferMemoryBarriers array.
3166  * pname:pBufferMemoryBarriers is a pointer to an array of
3167    slink:VkBufferMemoryBarrier structures.
3168  * pname:imageMemoryBarrierCount is the length of the
3169    pname:pImageMemoryBarriers array.
3170  * pname:pImageMemoryBarriers is a pointer to an array of
3171    slink:VkImageMemoryBarrier structures.
3172
3173When fname:vkCmdWaitEvents is submitted to a queue, it defines a memory
3174dependency between prior event signal operations on the same queue or the
3175host, and subsequent commands.
3176fname:vkCmdWaitEvents must: not be used to wait on event signal operations
3177occuring on other queues.
3178
3179The first synchronization scope only includes event signal operations that
3180operate on members of pname:pEvents, and the operations that happened-before
3181the event signal operations.
3182Event signal operations performed by flink:vkCmdSetEvent that occur earlier
3183in <<synchronization-submission-order,submission order>> are included in the
3184first synchronization scope, if the <<synchronization-pipeline-stages-order,
3185logically latest>> pipeline stage in their pname:stageMask parameter is
3186<<synchronization-pipeline-stages-order, logically earlier>> than or equal
3187to the <<synchronization-pipeline-stages-order, logically latest>> pipeline
3188stage in pname:srcStageMask.
3189Event signal operations performed by flink:vkSetEvent are only included in
3190the first synchronization scope if ename:VK_PIPELINE_STAGE_HOST_BIT is
3191included in pname:srcStageMask.
3192
3193The second <<synchronization-dependencies-scopes, synchronization scope>>
3194includes all commands that occur later in
3195<<synchronization-submission-order,submission order>>.
3196The second synchronization scope is limited to operations on the pipeline
3197stages determined by the <<synchronization-pipeline-stages-masks,
3198destination stage mask>> specified by pname:dstStageMask.
3199
3200The first <<synchronization-dependencies-access-scopes, access scope>> is
3201limited to access in the pipeline stages determined by the
3202<<synchronization-pipeline-stages-masks, source stage mask>> specified by
3203pname:srcStageMask.
3204Within that, the first access scope only includes the first access scopes
3205defined by elements of the pname:pMemoryBarriers,
3206pname:pBufferMemoryBarriers and pname:pImageMemoryBarriers arrays, which
3207each define a set of <<synchronization-memory-barriers, memory barriers>>.
3208If no memory barriers are specified, then the first access scope includes no
3209accesses.
3210
3211The second <<synchronization-dependencies-access-scopes, access scope>> is
3212limited to access in the pipeline stages determined by the
3213<<synchronization-pipeline-stages-masks, destination stage mask>> specified
3214by pname:dstStageMask.
3215Within that, the second access scope only includes the second access scopes
3216defined by elements of the pname:pMemoryBarriers,
3217pname:pBufferMemoryBarriers and pname:pImageMemoryBarriers arrays, which
3218each define a set of <<synchronization-memory-barriers, memory barriers>>.
3219If no memory barriers are specified, then the second access scope includes
3220no accesses.
3221
3222[NOTE]
3223.Note
3224====
3225flink:vkCmdWaitEvents is used with flink:vkCmdSetEvent to define a memory
3226dependency between two sets of action commands, roughly in the same way as
3227pipeline barriers, but split into two commands such that work between the
3228two may: execute unhindered.
3229====
3230
3231[NOTE]
3232.Note
3233====
3234Applications should: be careful to avoid race conditions when using events.
3235There is no direct ordering guarantee between a flink:vkCmdResetEvent
3236command and a flink:vkCmdWaitEvents command submitted after it, so some
3237other execution dependency must: be included between these commands (e.g. a
3238semaphore).
3239====
3240
3241.Valid Usage
3242****
3243  * [[VUID-vkCmdWaitEvents-srcStageMask-01158]]
3244    pname:srcStageMask must: be the bitwise OR of the pname:stageMask
3245    parameter used in previous calls to fname:vkCmdSetEvent with any of the
3246    members of pname:pEvents and ename:VK_PIPELINE_STAGE_HOST_BIT if any of
3247    the members of pname:pEvents was set using fname:vkSetEvent
3248  * [[VUID-vkCmdWaitEvents-srcStageMask-01159]]
3249    If the <<features-features-geometryShader,geometry shaders>> feature is
3250    not enabled, pname:srcStageMask must: not contain
3251    ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
3252  * [[VUID-vkCmdWaitEvents-dstStageMask-01160]]
3253    If the <<features-features-geometryShader,geometry shaders>> feature is
3254    not enabled, pname:dstStageMask must: not contain
3255    ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
3256  * [[VUID-vkCmdWaitEvents-srcStageMask-01161]]
3257    If the <<features-features-tessellationShader,tessellation shaders>>
3258    feature is not enabled, pname:srcStageMask must: not contain
3259    ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or
3260    ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
3261  * [[VUID-vkCmdWaitEvents-dstStageMask-01162]]
3262    If the <<features-features-tessellationShader,tessellation shaders>>
3263    feature is not enabled, pname:dstStageMask must: not contain
3264    ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or
3265    ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
3266  * [[VUID-vkCmdWaitEvents-pEvents-01163]]
3267    If pname:pEvents includes one or more events that will be signaled by
3268    fname:vkSetEvent after pname:commandBuffer has been submitted to a
3269    queue, then fname:vkCmdWaitEvents must: not be called inside a render
3270    pass instance
3271  * [[VUID-vkCmdWaitEvents-srcStageMask-01164]]
3272    Any pipeline stage included in pname:srcStageMask or pname:dstStageMask
3273    must: be supported by the capabilities of the queue family specified by
3274    the pname:queueFamilyIndex member of the slink:VkCommandPoolCreateInfo
3275    structure that was used to create the sname:VkCommandPool that
3276    pname:commandBuffer was allocated from, as specified in the
3277    <<synchronization-pipeline-stages-supported, table of supported pipeline
3278    stages>>.
3279  * [[VUID-vkCmdWaitEvents-pMemoryBarriers-01165]]
3280    Each element of pname:pMemoryBarriers, pname:pBufferMemoryBarriers or
3281    pname:pImageMemoryBarriers must: not have any access flag included in
3282    its pname:srcAccessMask member if that bit is not supported by any of
3283    the pipeline stages in pname:srcStageMask, as specified in the
3284    <<synchronization-access-types-supported, table of supported access
3285    types>>.
3286  * [[VUID-vkCmdWaitEvents-pMemoryBarriers-01166]]
3287    Each element of pname:pMemoryBarriers, pname:pBufferMemoryBarriers or
3288    pname:pImageMemoryBarriers must: not have any access flag included in
3289    its pname:dstAccessMask member if that bit is not supported by any of
3290    the pipeline stages in pname:dstStageMask, as specified in the
3291    <<synchronization-access-types-supported, table of supported access
3292    types>>.
3293ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
3294  * [[VUID-vkCmdWaitEvents-commandBuffer-01167]]
3295    pname:commandBuffer's current device mask must: include exactly one
3296    physical device.
3297endif::VK_VERSION_1_1,VK_KHR_device_group[]
3298****
3299
3300include::../validity/protos/vkCmdWaitEvents.txt[]
3301--
3302
3303
3304[[synchronization-pipeline-barriers]]
3305== Pipeline Barriers
3306
3307flink:vkCmdPipelineBarrier is a synchronization command that inserts a
3308dependency between commands submitted to the same queue, or between commands
3309in the same subpass.
3310
3311[open,refpage='vkCmdPipelineBarrier',desc='Insert a memory dependency',type='protos']
3312--
3313
3314To record a pipeline barrier, call:
3315
3316include::../api/protos/vkCmdPipelineBarrier.txt[]
3317
3318  * pname:commandBuffer is the command buffer into which the command is
3319    recorded.
3320  * pname:srcStageMask is a bitmask of elink:VkPipelineStageFlagBits
3321    specifying the <<synchronization-pipeline-stages-masks, source stage
3322    mask>>.
3323  * pname:dstStageMask is a bitmask of elink:VkPipelineStageFlagBits
3324    specifying the <<synchronization-pipeline-stages-masks, destination
3325    stage mask>>.
3326  * pname:dependencyFlags is a bitmask of elink:VkDependencyFlagBits
3327    specifying how execution and memory dependencies are formed.
3328  * pname:memoryBarrierCount is the length of the pname:pMemoryBarriers
3329    array.
3330  * pname:pMemoryBarriers is a pointer to an array of slink:VkMemoryBarrier
3331    structures.
3332  * pname:bufferMemoryBarrierCount is the length of the
3333    pname:pBufferMemoryBarriers array.
3334  * pname:pBufferMemoryBarriers is a pointer to an array of
3335    slink:VkBufferMemoryBarrier structures.
3336  * pname:imageMemoryBarrierCount is the length of the
3337    pname:pImageMemoryBarriers array.
3338  * pname:pImageMemoryBarriers is a pointer to an array of
3339    slink:VkImageMemoryBarrier structures.
3340
3341When flink:vkCmdPipelineBarrier is submitted to a queue, it defines a memory
3342dependency between commands that were submitted before it, and those
3343submitted after it.
3344
3345If flink:vkCmdPipelineBarrier was recorded outside a render pass instance,
3346the first <<synchronization-dependencies-scopes, synchronization scope>>
3347includes all commands that occur earlier in
3348<<synchronization-submission-order,submission order>>.
3349If flink:vkCmdPipelineBarrier was recorded inside a render pass instance,
3350the first synchronization scope includes only commands that occur earlier in
3351<<synchronization-submission-order,submission order>> within the same
3352subpass.
3353In either case, the first synchronization scope is limited to operations on
3354the pipeline stages determined by the
3355<<synchronization-pipeline-stages-masks, source stage mask>> specified by
3356pname:srcStageMask.
3357
3358If flink:vkCmdPipelineBarrier was recorded outside a render pass instance,
3359the second <<synchronization-dependencies-scopes, synchronization scope>>
3360includes all commands that occur later in
3361<<synchronization-submission-order,submission order>>.
3362If flink:vkCmdPipelineBarrier was recorded inside a render pass instance,
3363the second synchronization scope includes only commands that occur later in
3364<<synchronization-submission-order,submission order>> within the same
3365subpass.
3366In either case, the second synchronization scope is limited to operations on
3367the pipeline stages determined by the
3368<<synchronization-pipeline-stages-masks, destination stage mask>> specified
3369by pname:dstStageMask.
3370
3371The first <<synchronization-dependencies-access-scopes, access scope>> is
3372limited to access in the pipeline stages determined by the
3373<<synchronization-pipeline-stages-masks, source stage mask>> specified by
3374pname:srcStageMask.
3375Within that, the first access scope only includes the first access scopes
3376defined by elements of the pname:pMemoryBarriers,
3377pname:pBufferMemoryBarriers and pname:pImageMemoryBarriers arrays, which
3378each define a set of <<synchronization-memory-barriers, memory barriers>>.
3379If no memory barriers are specified, then the first access scope includes no
3380accesses.
3381
3382The second <<synchronization-dependencies-access-scopes, access scope>> is
3383limited to access in the pipeline stages determined by the
3384<<synchronization-pipeline-stages-masks, destination stage mask>> specified
3385by pname:dstStageMask.
3386Within that, the second access scope only includes the second access scopes
3387defined by elements of the pname:pMemoryBarriers,
3388pname:pBufferMemoryBarriers and pname:pImageMemoryBarriers arrays, which
3389each define a set of <<synchronization-memory-barriers, memory barriers>>.
3390If no memory barriers are specified, then the second access scope includes
3391no accesses.
3392
3393If pname:dependencyFlags includes ename:VK_DEPENDENCY_BY_REGION_BIT, then
3394any dependency between <<synchronization-framebuffer-regions,
3395framebuffer-space>> pipeline stages is
3396<<synchronization-framebuffer-regions, framebuffer-local>> - otherwise it is
3397<<synchronization-framebuffer-regions, framebuffer-global>>.
3398
3399.Valid Usage
3400****
3401  * [[VUID-vkCmdPipelineBarrier-srcStageMask-01168]]
3402    If the <<features-features-geometryShader,geometry shaders>> feature is
3403    not enabled, pname:srcStageMask must: not contain
3404    ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
3405  * [[VUID-vkCmdPipelineBarrier-dstStageMask-01169]]
3406    If the <<features-features-geometryShader,geometry shaders>> feature is
3407    not enabled, pname:dstStageMask must: not contain
3408    ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
3409  * [[VUID-vkCmdPipelineBarrier-srcStageMask-01170]]
3410    If the <<features-features-tessellationShader,tessellation shaders>>
3411    feature is not enabled, pname:srcStageMask must: not contain
3412    ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or
3413    ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
3414  * [[VUID-vkCmdPipelineBarrier-dstStageMask-01171]]
3415    If the <<features-features-tessellationShader,tessellation shaders>>
3416    feature is not enabled, pname:dstStageMask must: not contain
3417    ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or
3418    ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
3419  * [[VUID-vkCmdPipelineBarrier-pDependencies-02024]]
3420    If fname:vkCmdPipelineBarrier is called within a render pass instance,
3421    the render pass must: have been created with at least one
3422    sname:VkSubpassDependency instance in
3423    sname:VkRenderPassCreateInfo::pname:pDependencies that expresses a
3424    dependency from the current subpass to itself, and for which
3425    pname:srcStageMask contains a subset of the bit values in
3426    sname:VkSubpassDependency::pname:srcStageMask, pname:dstStageMask
3427    contains a subset of the bit values in
3428    sname:VkSubpassDependency::pname:dstStageMask, and pname:dependencyFlags
3429    is equal to sname:VkSubpassDependency::pname:dependencyFlags.
3430  * [[VUID-vkCmdPipelineBarrier-pMemoryBarriers-02026]]
3431    If fname:vkCmdPipelineBarrier is called within a render pass instance,
3432    for each element of pname:pMemoryBarriers and
3433    pname:pImageMemoryBarriers, the render pass must: have been defined with
3434    a sname:VkSubpassDependency self-dependency for the current subpass with
3435    valid pname:srcStageMask, pname:dstStageMask, and pname:dependencyFlags
3436    values such that stext:Vk*Barrier::pname:srcAccessMask contains a subset
3437    of the bit values in sname:VkSubpassDependency::pname:srcAccessMask and
3438    stext:Vk*Barrier::pname:dstAccessMask contains a subset of the bit
3439    values in sname:VkSubpassDependency::pname:dstAccessMask.
3440  * [[VUID-vkCmdPipelineBarrier-bufferMemoryBarrierCount-01178]]
3441    If fname:vkCmdPipelineBarrier is called within a render pass instance,
3442    pname:bufferMemoryBarrierCount must: be `0`
3443  * [[VUID-vkCmdPipelineBarrier-image-01179]]
3444    If fname:vkCmdPipelineBarrier is called within a render pass instance,
3445    the pname:image member of any element of pname:pImageMemoryBarriers
3446    must: be equal to one of the elements of pname:pAttachments that the
3447    current pname:framebuffer was created with, that is also referred to by
3448    one of the elements of the pname:pColorAttachments,
3449    pname:pResolveAttachments or pname:pDepthStencilAttachment members of
3450    the sname:VkSubpassDescription instance that the current subpass was
3451    created with
3452  * [[VUID-vkCmdPipelineBarrier-oldLayout-01180]]
3453    If fname:vkCmdPipelineBarrier is called within a render pass instance,
3454    the pname:oldLayout and pname:newLayout members of any element of
3455    pname:pImageMemoryBarriers must: be equal to the pname:layout member of
3456    an element of the pname:pColorAttachments, pname:pResolveAttachments or
3457    pname:pDepthStencilAttachment members of the sname:VkSubpassDescription
3458    instance that the current subpass was created with, that refers to the
3459    same pname:image
3460  * [[VUID-vkCmdPipelineBarrier-oldLayout-01181]]
3461    If fname:vkCmdPipelineBarrier is called within a render pass instance,
3462    the pname:oldLayout and pname:newLayout members of an element of
3463    pname:pImageMemoryBarriers must: be equal
3464  * [[VUID-vkCmdPipelineBarrier-srcQueueFamilyIndex-01182]]
3465    If fname:vkCmdPipelineBarrier is called within a render pass instance,
3466    the pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex members of
3467    any element of pname:pImageMemoryBarriers must: be
3468    ename:VK_QUEUE_FAMILY_IGNORED
3469  * [[VUID-vkCmdPipelineBarrier-srcStageMask-01183]]
3470    Any pipeline stage included in pname:srcStageMask or pname:dstStageMask
3471    must: be supported by the capabilities of the queue family specified by
3472    the pname:queueFamilyIndex member of the slink:VkCommandPoolCreateInfo
3473    structure that was used to create the sname:VkCommandPool that
3474    pname:commandBuffer was allocated from, as specified in the
3475    <<synchronization-pipeline-stages-supported, table of supported pipeline
3476    stages>>.
3477  * [[VUID-vkCmdPipelineBarrier-pMemoryBarriers-01184]]
3478    Each element of pname:pMemoryBarriers, pname:pBufferMemoryBarriers and
3479    pname:pImageMemoryBarriers must: not have any access flag included in
3480    its pname:srcAccessMask member if that bit is not supported by any of
3481    the pipeline stages in pname:srcStageMask, as specified in the
3482    <<synchronization-access-types-supported, table of supported access
3483    types>>.
3484  * [[VUID-vkCmdPipelineBarrier-pMemoryBarriers-01185]]
3485    Each element of pname:pMemoryBarriers, pname:pBufferMemoryBarriers and
3486    pname:pImageMemoryBarriers must: not have any access flag included in
3487    its pname:dstAccessMask member if that bit is not supported by any of
3488    the pipeline stages in pname:dstStageMask, as specified in the
3489    <<synchronization-access-types-supported, table of supported access
3490    types>>.
3491ifdef::VK_VERSION_1_1,VK_KHR_multiview[]
3492  * [[VUID-vkCmdPipelineBarrier-dependencyFlags-01186]]
3493    If fname:vkCmdPipelineBarrier is called outside of a render pass
3494    instance, pname:dependencyFlags must: not include
3495    ename:VK_DEPENDENCY_VIEW_LOCAL_BIT
3496endif::VK_VERSION_1_1,VK_KHR_multiview[]
3497****
3498
3499include::../validity/protos/vkCmdPipelineBarrier.txt[]
3500--
3501
3502[open,refpage='VkDependencyFlagBits',desc='Bitmask specifying how execution and memory dependencies are formed',type='enums']
3503--
3504
3505Bits which can: be set in fname:vkCmdPipelineBarrier::pname:dependencyFlags,
3506specifying how execution and memory dependencies are formed, are:
3507
3508include::../api/enums/VkDependencyFlagBits.txt[]
3509
3510  * ename:VK_DEPENDENCY_BY_REGION_BIT specifies that dependencies will be
3511    <<synchronization-framebuffer-regions, framebuffer-local>>.
3512ifdef::VK_VERSION_1_1,VK_KHR_multiview[]
3513  * ename:VK_DEPENDENCY_VIEW_LOCAL_BIT specifies that a
3514    <<synchronization-pipeline-barriers-subpass-self-dependencies, subpass
3515    has more than one view>>.
3516endif::VK_VERSION_1_1,VK_KHR_multiview[]
3517ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
3518  * ename:VK_DEPENDENCY_DEVICE_GROUP_BIT specifies that dependencies are
3519    <<synchronization-device-local-dependencies, non-device-local
3520    dependency>>.
3521endif::VK_VERSION_1_1,VK_KHR_device_group[]
3522
3523--
3524
3525[open,refpage='VkDependencyFlags',desc='Bitmask of VkDependencyFlagBits',type='enums']
3526--
3527include::../api/flags/VkDependencyFlags.txt[]
3528
3529sname:VkDependencyFlags is a bitmask type for setting a mask of zero or more
3530slink:VkDependencyFlagBits.
3531--
3532
3533
3534[[synchronization-pipeline-barriers-subpass-self-dependencies]]
3535=== Subpass Self-dependency
3536
3537If fname:vkCmdPipelineBarrier is called inside a render pass instance, the
3538following restrictions apply.
3539For a given subpass to allow a pipeline barrier, the render pass must:
3540declare a _self-dependency_ from that subpass to itself.
3541That is, there must: exist a sname:VkSubpassDependency in the subpass
3542dependency list for the render pass with pname:srcSubpass and
3543pname:dstSubpass equal to that subpass index.
3544More than one self-dependency can: be declared for each subpass.
3545Self-dependencies must: only include pipeline stage bits that are graphics
3546stages.
3547Self-dependencies must: not have any earlier pipeline stages depend on any
3548later pipeline stages (according to the order of
3549<<synchronization-pipeline-stages-types,graphics pipeline stages>>), unless
3550all of the stages are
3551<<synchronization-framebuffer-regions,framebuffer-space stages>>.
3552If the source and destination stage masks both include framebuffer-space
3553stages, then pname:dependencyFlags must: include
3554ename:VK_DEPENDENCY_BY_REGION_BIT.
3555ifdef::VK_VERSION_1_1,VK_KHR_multiview[]
3556If the subpass has more than one view, then pname:dependencyFlags must:
3557include ename:VK_DEPENDENCY_VIEW_LOCAL_BIT.
3558endif::VK_VERSION_1_1,VK_KHR_multiview[]
3559
3560A fname:vkCmdPipelineBarrier command inside a render pass instance must: be
3561a _subset_ of one of the self-dependencies of the subpass it is used in,
3562meaning that the stage masks and access masks must: each include only a
3563subset of the bits of the corresponding mask in that self-dependency.
3564If the self-dependency has ename:VK_DEPENDENCY_BY_REGION_BIT
3565ifdef::VK_VERSION_1_1,VK_KHR_multiview[]
3566or ename:VK_DEPENDENCY_VIEW_LOCAL_BIT
3567endif::VK_VERSION_1_1,VK_KHR_multiview[]
3568set, then so must: the pipeline barrier.
3569Pipeline barriers within a render pass instance can: only be types
3570sname:VkMemoryBarrier or sname:VkImageMemoryBarrier.
3571If a sname:VkImageMemoryBarrier is used, the image and image subresource
3572range specified in the barrier must: be a subset of one of the image views
3573used by the framebuffer in the current subpass.
3574Additionally, pname:oldLayout must: be equal to pname:newLayout, and both
3575the pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex must: be
3576ename:VK_QUEUE_FAMILY_IGNORED.
3577
3578
3579[[synchronization-memory-barriers]]
3580== Memory Barriers
3581
3582_Memory barriers_ are used to explicitly control access to buffer and image
3583subresource ranges.
3584Memory barriers are used to <<synchronization-queue-transfers, transfer
3585ownership between queue families>>,
3586<<synchronization-image-layout-transitions, change image layouts>>, and
3587define <<synchronization-dependencies-available-and-visible, availability
3588and visibility operations>>.
3589They explicitly define the <<synchronization-access-types, access types>>
3590and buffer and image subresource ranges that are included in the
3591<<synchronization-dependencies-access-scopes, access scopes>> of a memory
3592dependency that is created by a synchronization command that includes them.
3593
3594
3595[[synchronization-global-memory-barriers]]
3596=== Global Memory Barriers
3597
3598Global memory barriers apply to memory accesses involving all memory objects
3599that exist at the time of its execution.
3600
3601[open,refpage='VkMemoryBarrier',desc='Structure specifying a global memory barrier',type='structs']
3602--
3603
3604The sname:VkMemoryBarrier structure is defined as:
3605
3606include::../api/structs/VkMemoryBarrier.txt[]
3607
3608  * pname:sType is the type of this structure.
3609  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
3610  * pname:srcAccessMask is a bitmask of elink:VkAccessFlagBits specifying a
3611    <<synchronization-access-masks, source access mask>>.
3612  * pname:dstAccessMask is a bitmask of elink:VkAccessFlagBits specifying a
3613    <<synchronization-access-masks, destination access mask>>.
3614
3615The first <<synchronization-dependencies-access-scopes, access scope>> is
3616limited to access types in the <<synchronization-access-masks, source access
3617mask>> specified by pname:srcAccessMask.
3618
3619The second <<synchronization-dependencies-access-scopes, access scope>> is
3620limited to access types in the <<synchronization-access-masks, destination
3621access mask>> specified by pname:dstAccessMask.
3622
3623include::../validity/structs/VkMemoryBarrier.txt[]
3624--
3625
3626
3627[[synchronization-buffer-memory-barriers]]
3628=== Buffer Memory Barriers
3629
3630Buffer memory barriers only apply to memory accesses involving a specific
3631buffer range.
3632That is, a memory dependency formed from a buffer memory barrier is
3633<<synchronization-dependencies-access-scopes, scoped>> to access via the
3634specified buffer range.
3635Buffer memory barriers can: also be used to define a
3636<<synchronization-queue-transfers, queue family ownership transfer>> for the
3637specified buffer range.
3638
3639[open,refpage='VkBufferMemoryBarrier',desc='Structure specifying a buffer memory barrier',type='structs']
3640--
3641
3642The sname:VkBufferMemoryBarrier structure is defined as:
3643
3644include::../api/structs/VkBufferMemoryBarrier.txt[]
3645
3646  * pname:sType is the type of this structure.
3647  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
3648  * pname:srcAccessMask is a bitmask of elink:VkAccessFlagBits specifying a
3649    <<synchronization-access-masks, source access mask>>.
3650  * pname:dstAccessMask is a bitmask of elink:VkAccessFlagBits specifying a
3651    <<synchronization-access-masks, destination access mask>>.
3652  * pname:srcQueueFamilyIndex is the source queue family for a
3653    <<synchronization-queue-transfers, queue family ownership transfer>>.
3654  * pname:dstQueueFamilyIndex is the destination queue family for a
3655    <<synchronization-queue-transfers, queue family ownership transfer>>.
3656  * pname:buffer is a handle to the buffer whose backing memory is affected
3657    by the barrier.
3658  * pname:offset is an offset in bytes into the backing memory for
3659    pname:buffer; this is relative to the base offset as bound to the buffer
3660    (see flink:vkBindBufferMemory).
3661  * pname:size is a size in bytes of the affected area of backing memory for
3662    pname:buffer, or ename:VK_WHOLE_SIZE to use the range from pname:offset
3663    to the end of the buffer.
3664
3665The first <<synchronization-dependencies-access-scopes, access scope>> is
3666limited to access to memory through the specified buffer range, via access
3667types in the <<synchronization-access-masks, source access mask>> specified
3668by pname:srcAccessMask.
3669If pname:srcAccessMask includes ename:VK_ACCESS_HOST_WRITE_BIT, memory
3670writes performed by that access type are also made visible, as that access
3671type is not performed through a resource.
3672
3673The second <<synchronization-dependencies-access-scopes, access scope>> is
3674limited to access to memory through the specified buffer range, via access
3675types in the <<synchronization-access-masks, destination access mask>>.
3676specified by pname:dstAccessMask.
3677If pname:dstAccessMask includes ename:VK_ACCESS_HOST_WRITE_BIT or
3678ename:VK_ACCESS_HOST_READ_BIT, available memory writes are also made visible
3679to accesses of those types, as those access types are not performed through
3680a resource.
3681
3682If pname:srcQueueFamilyIndex is not equal to pname:dstQueueFamilyIndex, and
3683pname:srcQueueFamilyIndex is equal to the current queue family, then the
3684memory barrier defines a <<synchronization-queue-transfers-release, queue
3685family release operation>> for the specified buffer range, and the second
3686access scope includes no access, as if pname:dstAccessMask was `0`.
3687
3688If pname:dstQueueFamilyIndex is not equal to pname:srcQueueFamilyIndex, and
3689pname:dstQueueFamilyIndex is equal to the current queue family, then the
3690memory barrier defines a <<synchronization-queue-transfers-acquire, queue
3691family acquire operation>> for the specified buffer range, and the first
3692access scope includes no access, as if pname:srcAccessMask was `0`.
3693
3694.Valid Usage
3695****
3696  * [[VUID-VkBufferMemoryBarrier-offset-01187]]
3697    pname:offset must: be less than the size of pname:buffer
3698  * [[VUID-VkBufferMemoryBarrier-size-01188]]
3699    If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be
3700    greater than `0`
3701  * [[VUID-VkBufferMemoryBarrier-size-01189]]
3702    If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be
3703    less than or equal to than the size of pname:buffer minus pname:offset
3704ifndef::VK_VERSION_1_1,VK_KHR_external_memory[]
3705  * [[VUID-VkBufferMemoryBarrier-buffer-01190]]
3706    If pname:buffer was created with a sharing mode of
3707    ename:VK_SHARING_MODE_CONCURRENT, pname:srcQueueFamilyIndex and
3708    pname:dstQueueFamilyIndex must: both be ename:VK_QUEUE_FAMILY_IGNORED
3709endif::VK_VERSION_1_1,VK_KHR_external_memory[]
3710ifdef::VK_VERSION_1_1,VK_KHR_external_memory[]
3711  * [[VUID-VkBufferMemoryBarrier-buffer-01191]]
3712    If pname:buffer was created with a sharing mode of
3713    ename:VK_SHARING_MODE_CONCURRENT, at least one of
3714    pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex must: be
3715    ename:VK_QUEUE_FAMILY_IGNORED
3716  * [[VUID-VkBufferMemoryBarrier-buffer-01763]]
3717    If pname:buffer was created with a sharing mode of
3718    ename:VK_SHARING_MODE_CONCURRENT, and one of pname:srcQueueFamilyIndex
3719    and pname:dstQueueFamilyIndex is ename:VK_QUEUE_FAMILY_IGNORED, the
3720    other must: be ename:VK_QUEUE_FAMILY_IGNORED or a special queue family
3721    reserved for external memory ownership transfers, as described in
3722    <<synchronization-queue-transfers>>.
3723endif::VK_VERSION_1_1,VK_KHR_external_memory[]
3724ifndef::VK_VERSION_1_1,VK_KHR_external_memory[]
3725  * [[VUID-VkBufferMemoryBarrier-buffer-01192]]
3726    If pname:buffer was created with a sharing mode of
3727    ename:VK_SHARING_MODE_EXCLUSIVE, pname:srcQueueFamilyIndex and
3728    pname:dstQueueFamilyIndex must: either both be
3729    ename:VK_QUEUE_FAMILY_IGNORED, or both be a valid queue family (see
3730    <<devsandqueues-queueprops>>)
3731endif::VK_VERSION_1_1,VK_KHR_external_memory[]
3732ifdef::VK_VERSION_1_1,VK_KHR_external_memory[]
3733  * [[VUID-VkBufferMemoryBarrier-buffer-01193]]
3734    If pname:buffer was created with a sharing mode of
3735    ename:VK_SHARING_MODE_EXCLUSIVE and pname:srcQueueFamilyIndex is
3736    ename:VK_QUEUE_FAMILY_IGNORED, pname:dstQueueFamilyIndex must: also be
3737    ename:VK_QUEUE_FAMILY_IGNORED
3738  * [[VUID-VkBufferMemoryBarrier-buffer-01764]]
3739    If pname:buffer was created with a sharing mode of
3740    ename:VK_SHARING_MODE_EXCLUSIVE and pname:srcQueueFamilyIndex is not
3741    ename:VK_QUEUE_FAMILY_IGNORED, it must: be a valid queue family or a
3742    special queue family reserved for external memory transfers, as
3743    described in <<synchronization-queue-transfers>>.
3744  * [[VUID-VkBufferMemoryBarrier-buffer-01765]]
3745    If pname:buffer was created with a sharing mode of
3746    ename:VK_SHARING_MODE_EXCLUSIVE and pname:dstQueueFamilyIndex is not
3747    ename:VK_QUEUE_FAMILY_IGNORED, it must: be a valid queue family or a
3748    special queue family reserved for external memory transfers, as
3749    described in <<synchronization-queue-transfers>>.
3750endif::VK_VERSION_1_1,VK_KHR_external_memory[]
3751  * [[VUID-VkBufferMemoryBarrier-buffer-01196]]
3752    If pname:buffer was created with a sharing mode of
3753    ename:VK_SHARING_MODE_EXCLUSIVE, and pname:srcQueueFamilyIndex and
3754    pname:dstQueueFamilyIndex are not ename:VK_QUEUE_FAMILY_IGNORED, at
3755    least one of them must: be the same as the family of the queue that will
3756    execute this barrier
3757  * [[VUID-VkBufferMemoryBarrier-buffer-01931]]
3758    If pname:buffer is non-sparse then it must: be bound completely and
3759    contiguously to a single sname:VkDeviceMemory object
3760****
3761
3762include::../validity/structs/VkBufferMemoryBarrier.txt[]
3763--
3764
3765
3766[[synchronization-image-memory-barriers]]
3767=== Image Memory Barriers
3768
3769Image memory barriers only apply to memory accesses involving a specific
3770image subresource range.
3771That is, a memory dependency formed from an image memory barrier is
3772<<synchronization-dependencies-access-scopes, scoped>> to access via the
3773specified image subresource range.
3774Image memory barriers can: also be used to define
3775<<synchronization-image-layout-transitions, image layout transitions>> or a
3776<<synchronization-queue-transfers, queue family ownership transfer>> for the
3777specified image subresource range.
3778
3779[open,refpage='VkImageMemoryBarrier',desc='Structure specifying the parameters of an image memory barrier',type='structs']
3780--
3781
3782The sname:VkImageMemoryBarrier structure is defined as:
3783
3784include::../api/structs/VkImageMemoryBarrier.txt[]
3785
3786  * pname:sType is the type of this structure.
3787  * pname:pNext is `NULL` or a pointer to an extension-specific structure.
3788  * pname:srcAccessMask is a bitmask of elink:VkAccessFlagBits specifying a
3789    <<synchronization-access-masks, source access mask>>.
3790  * pname:dstAccessMask is a bitmask of elink:VkAccessFlagBits specifying a
3791    <<synchronization-access-masks, destination access mask>>.
3792  * pname:oldLayout is the old layout in an
3793    <<synchronization-image-layout-transitions, image layout transition>>.
3794  * pname:newLayout is the new layout in an
3795    <<synchronization-image-layout-transitions, image layout transition>>.
3796  * pname:srcQueueFamilyIndex is the source queue family for a
3797    <<synchronization-queue-transfers, queue family ownership transfer>>.
3798  * pname:dstQueueFamilyIndex is the destination queue family for a
3799    <<synchronization-queue-transfers, queue family ownership transfer>>.
3800  * pname:image is a handle to the image affected by this barrier.
3801  * pname:subresourceRange describes the <<resources-image-views, image
3802    subresource range>> within pname:image that is affected by this barrier.
3803
3804The first <<synchronization-dependencies-access-scopes, access scope>> is
3805limited to access to memory through the specified image subresource range,
3806via access types in the <<synchronization-access-masks, source access mask>>
3807specified by pname:srcAccessMask.
3808If pname:srcAccessMask includes ename:VK_ACCESS_HOST_WRITE_BIT, memory
3809writes performed by that access type are also made visible, as that access
3810type is not performed through a resource.
3811
3812The second <<synchronization-dependencies-access-scopes, access scope>> is
3813limited to access to memory through the specified image subresource range,
3814via access types in the <<synchronization-access-masks, destination access
3815mask>> specified by pname:dstAccessMask.
3816If pname:dstAccessMask includes ename:VK_ACCESS_HOST_WRITE_BIT or
3817ename:VK_ACCESS_HOST_READ_BIT, available memory writes are also made visible
3818to accesses of those types, as those access types are not performed through
3819a resource.
3820
3821If pname:srcQueueFamilyIndex is not equal to pname:dstQueueFamilyIndex, and
3822pname:srcQueueFamilyIndex is equal to the current queue family, then the
3823memory barrier defines a <<synchronization-queue-transfers-release, queue
3824family release operation>> for the specified image subresource range, and
3825the second access scope includes no access, as if pname:dstAccessMask was
3826`0`.
3827
3828If pname:dstQueueFamilyIndex is not equal to pname:srcQueueFamilyIndex, and
3829pname:dstQueueFamilyIndex is equal to the current queue family, then the
3830memory barrier defines a <<synchronization-queue-transfers-acquire, queue
3831family acquire operation>> for the specified image subresource range, and
3832the first access scope includes no access, as if pname:srcAccessMask was
3833`0`.
3834
3835If pname:oldLayout is not equal to pname:newLayout, then the memory barrier
3836defines an <<synchronization-image-layout-transitions, image layout
3837transition>> for the specified image subresource range.
3838
3839[[synchronization-image-barrier-layout-transition-order]]
3840Layout transitions that are performed via image memory barriers execute in
3841their entirety in <<synchronization-submission-order, submission order>>,
3842relative to other image layout transitions submitted to the same queue,
3843including those performed by <<renderpass, render passes>>.
3844In effect there is an implicit execution dependency from each such layout
3845transition to all layout transitions previously submitted to the same queue.
3846
3847ifdef::VK_EXT_sample_locations[]
3848
3849The image layout of each image subresource of a depth/stencil image created
3850with ename:VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT is
3851dependent on the last sample locations used to render to the image
3852subresource as a depth/stencil attachment, thus when the pname:image member
3853of an sname:VkImageMemoryBarrier is an image created with this flag the
3854application can: chain a slink:VkSampleLocationsInfoEXT structure to the
3855pname:pNext chain of sname:VkImageMemoryBarrier to specify the sample
3856locations to use during the image layout transition.
3857
3858If the sname:VkSampleLocationsInfoEXT structure in the pname:pNext chain of
3859sname:VkImageMemoryBarrier does not match the sample location state last
3860used to render to the image subresource range specified by
3861pname:subresourceRange or if no sname:VkSampleLocationsInfoEXT structure is
3862in the pname:pNext chain of sname:VkImageMemoryBarrier then the contents of
3863the given image subresource range becomes undefined as if pname:oldLayout
3864would equal ename:VK_IMAGE_LAYOUT_UNDEFINED.
3865
3866endif::VK_EXT_sample_locations[]
3867
3868ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[]
3869
3870If pname:image has a multi-planar format and the image is _disjoint_, then
3871including ename:VK_IMAGE_ASPECT_COLOR_BIT in the pname:aspectMask member of
3872pname:subresourceRange is equivalent to including
3873ename:VK_IMAGE_ASPECT_PLANE_0_BIT, ename:VK_IMAGE_ASPECT_PLANE_1_BIT, and
3874(for three-plane formats only) ename:VK_IMAGE_ASPECT_PLANE_2_BIT.
3875
3876endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[]
3877
3878.Valid Usage
3879****
3880  * [[VUID-VkImageMemoryBarrier-oldLayout-01197]]
3881    pname:oldLayout must: be ename:VK_IMAGE_LAYOUT_UNDEFINED or the current
3882    layout of the image subresources affected by the barrier
3883  * [[VUID-VkImageMemoryBarrier-newLayout-01198]]
3884    pname:newLayout must: not be ename:VK_IMAGE_LAYOUT_UNDEFINED or
3885    ename:VK_IMAGE_LAYOUT_PREINITIALIZED
3886ifndef::VK_VERSION_1_1,VK_KHR_external_memory[]
3887  * [[VUID-VkImageMemoryBarrier-image-01199]]
3888    If pname:image was created with a sharing mode of
3889    ename:VK_SHARING_MODE_CONCURRENT, pname:srcQueueFamilyIndex and
3890    pname:dstQueueFamilyIndex must: both be ename:VK_QUEUE_FAMILY_IGNORED
3891endif::VK_VERSION_1_1,VK_KHR_external_memory[]
3892ifdef::VK_VERSION_1_1,VK_KHR_external_memory[]
3893  * [[VUID-VkImageMemoryBarrier-image-01381]]
3894    If pname:image was created with a sharing mode of
3895    ename:VK_SHARING_MODE_CONCURRENT, at least one of
3896    pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex must: be
3897    ename:VK_QUEUE_FAMILY_IGNORED
3898  * [[VUID-VkImageMemoryBarrier-image-01766]]
3899    If pname:image was created with a sharing mode of
3900    ename:VK_SHARING_MODE_CONCURRENT, and one of pname:srcQueueFamilyIndex
3901    and pname:dstQueueFamilyIndex is ename:VK_QUEUE_FAMILY_IGNORED, the
3902    other must: be ename:VK_QUEUE_FAMILY_IGNORED or a special queue family
3903    reserved for external memory transfers, as described in
3904    <<synchronization-queue-transfers>>.
3905endif::VK_VERSION_1_1,VK_KHR_external_memory[]
3906ifndef::VK_VERSION_1_1,VK_KHR_external_memory[]
3907  * [[VUID-VkImageMemoryBarrier-image-01200]]
3908    If pname:image was created with a sharing mode of
3909    ename:VK_SHARING_MODE_EXCLUSIVE, pname:srcQueueFamilyIndex and
3910    pname:dstQueueFamilyIndex must: either both be
3911    ename:VK_QUEUE_FAMILY_IGNORED, or both be a valid queue family (see
3912    <<devsandqueues-queueprops>>).
3913endif::VK_VERSION_1_1,VK_KHR_external_memory[]
3914ifdef::VK_VERSION_1_1,VK_KHR_external_memory[]
3915  * [[VUID-VkImageMemoryBarrier-image-01201]]
3916    If pname:image was created with a sharing mode of
3917    ename:VK_SHARING_MODE_EXCLUSIVE and pname:srcQueueFamilyIndex is
3918    ename:VK_QUEUE_FAMILY_IGNORED, pname:dstQueueFamilyIndex must: also be
3919    ename:VK_QUEUE_FAMILY_IGNORED.
3920  * [[VUID-VkImageMemoryBarrier-image-01767]]
3921    If pname:image was created with a sharing mode of
3922    ename:VK_SHARING_MODE_EXCLUSIVE and pname:srcQueueFamilyIndex is not
3923    ename:VK_QUEUE_FAMILY_IGNORED, it must: be a valid queue family or a
3924    special queue family reserved for external memory transfers, as
3925    described in <<synchronization-queue-transfers>>.
3926  * [[VUID-VkImageMemoryBarrier-image-01768]]
3927    If pname:image was created with a sharing mode of
3928    ename:VK_SHARING_MODE_EXCLUSIVE and pname:dstQueueFamilyIndex is not
3929    ename:VK_QUEUE_FAMILY_IGNORED, it must: be a valid queue family or a
3930    special queue family reserved for external memory transfers, as
3931    described in <<synchronization-queue-transfers>>.
3932endif::VK_VERSION_1_1,VK_KHR_external_memory[]
3933  * [[VUID-VkImageMemoryBarrier-image-01205]]
3934    If pname:image was created with a sharing mode of
3935    ename:VK_SHARING_MODE_EXCLUSIVE, and pname:srcQueueFamilyIndex and
3936    pname:dstQueueFamilyIndex are not ename:VK_QUEUE_FAMILY_IGNORED, at
3937    least one of them must: be the same as the family of the queue that will
3938    execute this barrier
3939  * [[VUID-VkImageMemoryBarrier-subresourceRange-01486]]
3940    pname:subresourceRange.baseMipLevel must: be less than the
3941    pname:mipLevels specified in slink:VkImageCreateInfo when pname:image
3942    was created
3943  * [[VUID-VkImageMemoryBarrier-subresourceRange-01724]]
3944    If pname:subresourceRange.levelCount is not
3945    ename:VK_REMAINING_MIP_LEVELS, [eq]#pname:subresourceRange.baseMipLevel
3946    {plus} pname:subresourceRange.levelCount# must: be less than or equal to
3947    the pname:mipLevels specified in slink:VkImageCreateInfo when
3948    pname:image was created
3949  * [[VUID-VkImageMemoryBarrier-subresourceRange-01488]]
3950    pname:subresourceRange.baseArrayLayer must: be less than the
3951    pname:arrayLayers specified in slink:VkImageCreateInfo when pname:image
3952    was created
3953  * [[VUID-VkImageMemoryBarrier-subresourceRange-01725]]
3954    If pname:subresourceRange.layerCount is not
3955    ename:VK_REMAINING_ARRAY_LAYERS,
3956    [eq]#pname:subresourceRange.baseArrayLayer {plus}
3957    pname:subresourceRange.layerCount# must: be less than or equal to the
3958    pname:arrayLayers specified in slink:VkImageCreateInfo when pname:image
3959    was created
3960  * [[VUID-VkImageMemoryBarrier-image-01207]]
3961    If pname:image has a depth/stencil format with both depth and stencil
3962    components, then the pname:aspectMask member of pname:subresourceRange
3963    must: include both ename:VK_IMAGE_ASPECT_DEPTH_BIT and
3964    ename:VK_IMAGE_ASPECT_STENCIL_BIT
3965ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[]
3966  * [[VUID-VkImageMemoryBarrier-image-01671]]
3967    If pname:image has a single-plane color format or is not _disjoint_,
3968    then the pname:aspectMask member of pname:subresourceRange must: be
3969    ename:VK_IMAGE_ASPECT_COLOR_BIT
3970  * [[VUID-VkImageMemoryBarrier-image-01672]]
3971    If pname:image has a multi-planar format and the image is _disjoint_,
3972    then the pname:aspectMask member of pname:subresourceRange must: include
3973    either at least one of ename:VK_IMAGE_ASPECT_PLANE_0_BIT,
3974    ename:VK_IMAGE_ASPECT_PLANE_1_BIT, and
3975    ename:VK_IMAGE_ASPECT_PLANE_2_BIT; or must: include
3976    ename:VK_IMAGE_ASPECT_COLOR_BIT
3977  * [[VUID-VkImageMemoryBarrier-image-01673]]
3978    If pname:image has a multi-planar format with only two planes, then the
3979    pname:aspectMask member of pname:subresourceRange must: not include
3980    ename:VK_IMAGE_ASPECT_PLANE_2_BIT
3981endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[]
3982  * [[VUID-VkImageMemoryBarrier-oldLayout-01208]]
3983    If either pname:oldLayout or pname:newLayout is
3984    ename:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL then pname:image must:
3985    have been created with ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT set
3986  * [[VUID-VkImageMemoryBarrier-oldLayout-01209]]
3987    If either pname:oldLayout or pname:newLayout is
3988    ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL then pname:image
3989    must: have been created with
3990    ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set
3991  * [[VUID-VkImageMemoryBarrier-oldLayout-01210]]
3992    If either pname:oldLayout or pname:newLayout is
3993    ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL then pname:image
3994    must: have been created with
3995    ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set
3996ifdef::VK_VERSION_1_1,VK_KHR_maintenance2[]
3997  * [[VUID-VkImageMemoryBarrier-oldLayout-01658]]
3998    If either pname:oldLayout or pname:newLayout is
3999    ename:VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL then
4000    pname:image must: have been created with
4001    ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set
4002  * [[VUID-VkImageMemoryBarrier-oldLayout-01659]]
4003    If either pname:oldLayout or pname:newLayout is
4004    ename:VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL then
4005    pname:image must: have been created with
4006    ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set
4007endif::VK_VERSION_1_1,VK_KHR_maintenance2[]
4008  * [[VUID-VkImageMemoryBarrier-oldLayout-01211]]
4009    If either pname:oldLayout or pname:newLayout is
4010    ename:VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL then pname:image must:
4011    have been created with ename:VK_IMAGE_USAGE_SAMPLED_BIT or
4012    ename:VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set
4013  * [[VUID-VkImageMemoryBarrier-oldLayout-01212]]
4014    If either pname:oldLayout or pname:newLayout is
4015    ename:VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL then pname:image must: have
4016    been created with ename:VK_IMAGE_USAGE_TRANSFER_SRC_BIT set
4017  * [[VUID-VkImageMemoryBarrier-oldLayout-01213]]
4018    If either pname:oldLayout or pname:newLayout is
4019    ename:VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL then pname:image must: have
4020    been created with ename:VK_IMAGE_USAGE_TRANSFER_DST_BIT set
4021  * [[VUID-VkImageMemoryBarrier-image-01932]]
4022    If pname:image is non-sparse then it must: be bound completely and
4023    contiguously to a single sname:VkDeviceMemory object
4024****
4025
4026include::../validity/structs/VkImageMemoryBarrier.txt[]
4027--
4028
4029
4030[[synchronization-queue-transfers]]
4031=== Queue Family Ownership Transfer
4032
4033Resources created with a elink:VkSharingMode of
4034ename:VK_SHARING_MODE_EXCLUSIVE must: have their ownership explicitly
4035transferred from one queue family to another in order to access their
4036content in a well-defined manner on a queue in a different queue family.
4037ifdef::VK_VERSION_1_1,VK_KHR_external_memory[]
4038Resources shared with external APIs or instances using external memory must:
4039also explicitly manage ownership transfers between local and external queues
4040(or equivalent constructs in external APIs) regardless of the
4041elink:VkSharingMode specified when creating them.
4042The special queue family index ename:VK_QUEUE_FAMILY_EXTERNAL represents any
4043queue external to the resource's current Vulkan instance, as long as the
4044queue uses the same underlying physical device
4045ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
4046or device group
4047endif::VK_VERSION_1_1,VK_KHR_device_group[]
4048and uses the same driver version as the resource's slink:VkDevice, as
4049indicated by slink:VkPhysicalDeviceIDProperties::pname:deviceUUID and
4050slink:VkPhysicalDeviceIDProperties::pname:driverUUID.
4051ifdef::VK_EXT_queue_family_foreign[]
4052The special queue family index ename:VK_QUEUE_FAMILY_FOREIGN_EXT represents
4053any queue external to the resource's current Vulkan instance, regardless of
4054the queue's underlying physical device or driver version.
4055This includes, for example, queues for fixed-function image processing
4056devices, media codec devices, and display devices, as well as all queues
4057that use the same underlying physical device
4058ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
4059(or device group)
4060endif::VK_VERSION_1_1,VK_KHR_device_group[]
4061and driver version as the resource's slink:VkDevice.
4062endif::VK_EXT_queue_family_foreign[]
4063endif::VK_VERSION_1_1,VK_KHR_external_memory[]
4064If memory dependencies are correctly expressed between uses of such a
4065resource between two queues in different families, but no ownership transfer
4066is defined, the contents of that resource are undefined for any read
4067accesses performed by the second queue family.
4068
4069[NOTE]
4070.Note
4071====
4072If an application does not need the contents of a resource to remain valid
4073when transferring from one queue family to another, then the ownership
4074transfer should: be skipped.
4075====
4076
4077ifdef::VK_EXT_queue_family_foreign[]
4078[NOTE]
4079.Note
4080====
4081Applications should expect transfers to/from
4082ename:VK_QUEUE_FAMILY_FOREIGN_EXT to be more expensive than transfers
4083to/from ename:VK_QUEUE_FAMILY_EXTERNAL_KHR.
4084====
4085endif::VK_EXT_queue_family_foreign[]
4086
4087A queue family ownership transfer consists of two distinct parts:
4088
4089  . Release exclusive ownership from the source queue family
4090  . Acquire exclusive ownership for the destination queue family
4091
4092An application must: ensure that these operations occur in the correct order
4093by defining an execution dependency between them, e.g. using a semaphore.
4094
4095[[synchronization-queue-transfers-release]] A _release operation_ is used to
4096release exclusive ownership of a range of a buffer or image subresource
4097range.
4098A release operation is defined by executing a
4099<<synchronization-buffer-memory-barriers, buffer memory barrier>> (for a
4100buffer range) or an <<synchronization-image-memory-barriers, image memory
4101barrier>> (for an image subresource range), on a queue from the source queue
4102family.
4103The pname:srcQueueFamilyIndex parameter of the barrier must: be set to the
4104source queue family index, and the pname:dstQueueFamilyIndex parameter to
4105the destination queue family index.
4106pname:dstStageMask is ignored for such a barrier, such that no visibility
4107operation is executed - the value of this mask does not affect the validity
4108of the barrier.
4109The release operation happens-after the availability operation.
4110
4111[[synchronization-queue-transfers-acquire]] An _acquire operation_ is used
4112to acquire exclusive ownership of a range of a buffer or image subresource
4113range.
4114An acquire operation is defined by executing a
4115<<synchronization-buffer-memory-barriers, buffer memory barrier>> (for a
4116buffer range) or an <<synchronization-image-memory-barriers, image memory
4117barrier>> (for an image subresource range), on a queue from the destination
4118queue family.
4119The buffer range or image subresource range specified in an acquire
4120operation must: match exactly that of a previous release operation.
4121The pname:srcQueueFamilyIndex parameter of the barrier must: be set to the
4122source queue family index, and the pname:dstQueueFamilyIndex parameter to
4123the destination queue family index.
4124pname:srcStageMask is ignored for such a barrier, such that no availability
4125operation is executed - the value of this mask does not affect the validity
4126of the barrier.
4127The acquire operation happens-before the visibility operation.
4128
4129[NOTE]
4130.Note
4131====
4132Whilst it is not invalid to provide destination or source access masks for
4133memory barriers used for release or acquire operations, respectively, they
4134have no practical effect.
4135Access after a release operation has undefined results, and so visibility
4136for those accesses has no practical effect.
4137Similarly, write access before an acquire operation will produce undefined
4138results for future access, so availability of those writes has no practical
4139use.
4140In an earlier version of the specification, these were required to match on
4141both sides - but this was subsequently relaxed.
4142These masks should: be set to 0.
4143====
4144
4145If the transfer is via an image memory barrier, and an
4146<<synchronization-image-layout-transitions, image layout transition>> is
4147desired, then the values of pname:oldLayout and pname:newLayout in the
4148release memory barrier must: be equal to values of pname:oldLayout and
4149pname:newLayout in the acquire memory barrier.
4150Although the image layout transition is submitted twice, it will only be
4151executed once.
4152A layout transition specified in this way happens-after the release
4153operation and happens-before the acquire operation.
4154
4155If the values of pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex are
4156equal, no ownership transfer is performed, and the barrier operates as if
4157they were both set to ename:VK_QUEUE_FAMILY_IGNORED.
4158
4159Queue family ownership transfers may: perform read and write accesses on all
4160memory bound to the image subresource or buffer range, so applications must:
4161ensure that all memory writes have been made
4162<<synchronization-dependencies-available-and-visible, available>> before a
4163queue family ownership transfer is executed.
4164Available memory is automatically made visible to queue family release and
4165acquire operations, and writes performed by those operations are
4166automatically made available.
4167
4168Once a queue family has acquired ownership of a buffer range or image
4169subresource range of an ename:VK_SHARING_MODE_EXCLUSIVE resource, its
4170contents are undefined to other queue families unless ownership is
4171transferred.
4172The contents of any portion of another resource which aliases memory that is
4173bound to the transferred buffer or image subresource range are undefined
4174after a release or acquire operation.
4175
4176
4177[[synchronization-wait-idle]]
4178== Wait Idle Operations
4179
4180[open,refpage='vkQueueWaitIdle',desc='Wait for a queue to become idle',type='protos']
4181--
4182
4183To wait on the host for the completion of outstanding queue operations for a
4184given queue, call:
4185
4186include::../api/protos/vkQueueWaitIdle.txt[]
4187
4188  * pname:queue is the queue on which to wait.
4189
4190fname:vkQueueWaitIdle is equivalent to submitting a fence to a queue and
4191waiting with an infinite timeout for that fence to signal.
4192
4193include::../validity/protos/vkQueueWaitIdle.txt[]
4194--
4195
4196[open,refpage='vkDeviceWaitIdle',desc='Wait for a device to become idle',type='protos']
4197--
4198
4199To wait on the host for the completion of outstanding queue operations for
4200all queues on a given logical device, call:
4201
4202include::../api/protos/vkDeviceWaitIdle.txt[]
4203
4204  * pname:device is the logical device to idle.
4205
4206fname:vkDeviceWaitIdle is equivalent to calling fname:vkQueueWaitIdle for
4207all queues owned by pname:device.
4208
4209include::../validity/protos/vkDeviceWaitIdle.txt[]
4210--
4211
4212
4213[[synchronization-submission-host-writes]]
4214== Host Write Ordering Guarantees
4215
4216When batches of command buffers are submitted to a queue via
4217flink:vkQueueSubmit, it defines a memory dependency with prior host
4218operations, and execution of command buffers submitted to the queue.
4219
4220The first <<synchronization-dependencies-scopes, synchronization scope>> is
4221defined by the host execution model, but includes execution of
4222flink:vkQueueSubmit on the host and anything that happened-before it.
4223
4224The second <<synchronization-dependencies-scopes, synchronization scope>>
4225includes all commands submitted in the same <<devsandqueues-submission,
4226queue submission>>, and all commands that occur later in
4227<<synchronization-submission-order,submission order>>.
4228
4229The first <<synchronization-dependencies-access-scopes, access scope>>
4230includes all host writes to mappable device memory that are either coherent,
4231or have been flushed with flink:vkFlushMappedMemoryRanges.
4232
4233The second <<synchronization-dependencies-access-scopes, access scope>>
4234includes all memory access performed by the device.
4235
4236
4237ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
4238
4239[[synchronization-device-group]]
4240== Synchronization and Multiple Physical Devices
4241
4242If a logical device includes more than one physical device, then fences,
4243semaphores, and events all still have a single instance of the signaled
4244state.
4245
4246A fence becomes signaled when all physical devices complete the necessary
4247queue operations.
4248
4249Semaphore wait and signal operations all include a device index that is the
4250sole physical device that performs the operation.
4251These indices are provided in the slink:VkDeviceGroupSubmitInfo and
4252slink:VkDeviceGroupBindSparseInfo structures.
4253Semaphores are not exclusively owned by any physical device.
4254For example, a semaphore can be signaled by one physical device and then
4255waited on by a different physical device.
4256
4257An event can: only be waited on by the same physical device that signaled it
4258(or the host).
4259
4260endif::VK_VERSION_1_1,VK_KHR_device_group[]
4261