| // Copyright 2015-2021 The Khronos Group, Inc. |
| // |
| // SPDX-License-Identifier: CC-BY-4.0 |
| |
| [[synchronization]] |
| = Synchronization and Cache Control |
| |
| Synchronization of access to resources is primarily the responsibility of |
| the application in Vulkan. |
| The order of execution of commands with respect to the host and other |
| commands on the device has few implicit guarantees, and needs to be |
| explicitly specified. |
| Memory caches and other optimizations are also explicitly managed, requiring |
| that the flow of data through the system is largely under application |
| control. |
| |
| Whilst some implicit guarantees exist between commands, five explicit |
| synchronization mechanisms are exposed by Vulkan: |
| |
| <<synchronization-fences,Fences>>:: |
| Fences can: be used to communicate to the host that execution of some |
| task on the device has completed. |
| |
| <<synchronization-semaphores,Semaphores>>:: |
| Semaphores can: be used to control resource access across multiple |
| queues. |
| |
| <<synchronization-events,Events>>:: |
| Events provide a fine-grained synchronization primitive which can: be |
| signaled either within a command buffer or by the host, and can: be |
| waited upon within a command buffer or queried on the host. |
| |
| <<synchronization-pipeline-barriers,Pipeline Barriers>>:: |
| Pipeline barriers also provide synchronization control within a command |
| buffer, but at a single point, rather than with separate signal and wait |
| operations. |
| |
| <<renderpass,Render Passes>>:: |
| Render passes provide a useful synchronization framework for most |
| rendering tasks, built upon the concepts in this chapter. |
| Many cases that would otherwise need an application to use other |
| synchronization primitives can: be expressed more efficiently as part of |
| a render pass. |
| |
| |
| [[synchronization-dependencies]] |
| == Execution and Memory Dependencies |
| |
| An _operation_ is an arbitrary amount of work to be executed on the host, a |
| device, or an external entity such as a presentation engine. |
| Synchronization commands introduce explicit _execution dependencies_, and |
| _memory dependencies_ between two sets of operations defined by the |
| command's two _synchronization scopes_. |
| |
| [[synchronization-dependencies-scopes]] |
| The synchronization scopes define which other operations a synchronization |
| command is able to create execution dependencies with. |
| Any type of operation that is not in a synchronization command's |
| synchronization scopes will not be included in the resulting dependency. |
| For example, for many synchronization commands, the synchronization scopes |
| can: be limited to just operations executing in specific |
| <<synchronization-pipeline-stages,pipeline stages>>, which allows other |
| pipeline stages to be excluded from a dependency. |
| Other scoping options are possible, depending on the particular command. |
| |
| [[synchronization-dependencies-execution]] |
| An _execution dependency_ is a guarantee that for two sets of operations, |
| the first set must: _happen-before_ the second set. |
| If an operation happens-before another operation, then the first operation |
| must: complete before the second operation is initiated. |
| More precisely: |
| |
| * Let *A* and *B* be separate sets of operations. |
| * Let *S* be a synchronization command. |
| * Let *A~S~* and *B~S~* be the synchronization scopes of *S*. |
| * Let *A'* be the intersection of sets *A* and *A~S~*. |
| * Let *B'* be the intersection of sets *B* and *B~S~*. |
| * Submitting *A*, *S* and *B* for execution, in that order, will result in |
| execution dependency *E* between *A'* and *B'*. |
| * Execution dependency *E* guarantees that *A'* happens-before *B'*. |
| |
| [[synchronization-dependencies-chains]] |
| An _execution dependency chain_ is a sequence of execution dependencies that |
| form a happens-before relation between the first dependency's *A'* and the |
| final dependency's *B'*. |
| For each consecutive pair of execution dependencies, a chain exists if the |
| intersection of *B~S~* in the first dependency and *A~S~* in the second |
| dependency is not an empty set. |
| The formation of a single execution dependency from an execution dependency |
| chain can be described by substituting the following in the description of |
| execution dependencies: |
| |
| * Let *S* be a set of synchronization commands that generate an execution |
| dependency chain. |
| * Let *A~S~* be the first synchronization scope of the first command in |
| *S*. |
| * Let *B~S~* be the second synchronization scope of the last command in |
| *S*. |
| |
| Execution dependencies alone are not sufficient to guarantee that values |
| resulting from writes in one set of operations can: be read from another set |
| of operations. |
| |
| [[synchronization-dependencies-available-and-visible]] |
| Three additional types of operations are used to control memory access. |
| _Availability operations_ cause the values generated by specified memory |
| write accesses to become _available_ to a memory domain for future access. |
| Any available value remains available until a subsequent write to the same |
| memory location occurs (whether it is made available or not) or the memory |
| is freed. |
| _Memory domain operations_ cause writes that are available to a source |
| memory domain to become available to a destination memory domain (an example |
| of this is making writes available to the host domain available to the |
| device domain). |
| _Visibility operations_ cause values available to a memory domain to become |
| _visible_ to specified memory accesses. |
| |
| ifdef::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] |
| Availability, visibility, memory domains, and memory domain operations are |
| formally defined in the <<memory-model-availability-visibility,Availability |
| and Visibility>> section of the <<memory-model,Memory Model>> chapter. |
| Which API operations perform each of these operations is defined in |
| <<memory-model-vulkan-availability-visibility,Availability, Visibility, and |
| Domain Operations>>. |
| endif::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] |
| |
| [[synchronization-dependencies-memory]] |
| A _memory dependency_ is an execution dependency which includes availability |
| and visibility operations such that: |
| |
| * The first set of operations happens-before the availability operation. |
| * The availability operation happens-before the visibility operation. |
| * The visibility operation happens-before the second set of operations. |
| |
| Once written values are made visible to a particular type of memory access, |
| they can: be read or written by that type of memory access. |
| Most synchronization commands in Vulkan define a memory dependency. |
| |
| [[synchronization-dependencies-access-scopes]] |
| The specific memory accesses that are made available and visible are defined |
| by the _access scopes_ of a memory dependency. |
| Any type of access that is in a memory dependency's first access scope and |
| occurs in *A'* is made available. |
| Any type of access that is in a memory dependency's second access scope and |
| occurs in *B'* has any available writes made visible to it. |
| Any type of operation that is not in a synchronization command's access |
| scopes will not be included in the resulting dependency. |
| |
| A memory dependency enforces availability and visibility of memory accesses |
| and execution order between two sets of operations. |
| Adding to the description of <<synchronization-dependencies-chains, |
| execution dependency chains>>: |
| |
| * Let *a* be the set of memory accesses performed by *A'*. |
| * Let *b* be the set of memory accesses performed by *B'*. |
| * Let *a~S~* be the first access scope of the first command in *S*. |
| * Let *b~S~* be the second access scope of the last command in *S*. |
| * Let *a'* be the intersection of sets *a* and *a~S~*. |
| * Let *b'* be the intersection of sets *b* and *b~S~*. |
| * Submitting *A*, *S* and *B* for execution, in that order, will result in |
| a memory dependency *m* between *A'* and *B'*. |
| * Memory dependency *m* guarantees that: |
| ** Memory writes in *a'* are made available. |
| ** Available memory writes, including those from *a'*, are made visible to |
| *b'*. |
| |
| [NOTE] |
| .Note |
| ==== |
| Execution and memory dependencies are used to solve data hazards, i.e. to |
| ensure that read and write operations occur in a well-defined order. |
| Write-after-read hazards can be solved with just an execution dependency, |
| but read-after-write and write-after-write hazards need appropriate memory |
| dependencies to be included between them. |
| If an application does not include dependencies to solve these hazards, the |
| results and execution orders of memory accesses are undefined:. |
| ==== |
| |
| |
| [[synchronization-image-layout-transitions]] |
| === Image Layout Transitions |
| |
| Image subresources can: be transitioned from one <<resources-image-layouts, |
| layout>> to another as part of a <<synchronization-dependencies-memory, |
| memory dependency>> (e.g. by using an |
| <<synchronization-image-memory-barriers,image memory barrier>>). |
| When a layout transition is specified in a memory dependency, it |
| happens-after the availability operations in the memory dependency, and |
| happens-before the visibility operations. |
| Image layout transitions may: perform read and write accesses on all memory |
| bound to the image subresource range, so applications must: ensure that all |
| memory writes have been made |
| <<synchronization-dependencies-available-and-visible, available>> before a |
| layout transition is executed. |
| Available memory is automatically made visible to a layout transition, and |
| writes performed by a layout transition are automatically made available. |
| |
| Layout transitions always apply to a particular image subresource range, and |
| specify both an old layout and new layout. |
| The old layout must: either be ename:VK_IMAGE_LAYOUT_UNDEFINED, or match the |
| current layout of the image subresource range. |
| If the old layout matches the current layout of the image subresource range, |
| the transition preserves the contents of that range. |
| If the old layout is ename:VK_IMAGE_LAYOUT_UNDEFINED, the contents of that |
| range may: be discarded. |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_device_group[] |
| As image layout transitions may: perform read and write accesses on the |
| memory bound to the image, if the image subresource affected by the layout |
| transition is bound to peer memory for any device in the current device mask |
| then the memory heap the bound memory comes from must: support the |
| ename:VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT and |
| ename:VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT capabilities as returned by |
| flink:vkGetDeviceGroupPeerMemoryFeatures. |
| endif::VK_VERSION_1_1,VK_KHR_device_group[] |
| |
| [NOTE] |
| .Note |
| ==== |
| Applications must: ensure that layout transitions happen-after all |
| operations accessing the image with the old layout, and happen-before any |
| operations that will access the image with the new layout. |
| Layout transitions are potentially read/write operations, so not defining |
| appropriate memory dependencies to guarantee this will result in a data |
| race. |
| ==== |
| |
| Image layout transitions interact with <<resources-memory-aliasing,memory |
| aliasing>>. |
| |
| |
| [[synchronization-image-barrier-layout-transition-order]] |
| Layout transitions that are performed via image memory barriers execute in |
| their entirety in <<synchronization-submission-order, submission order>>, |
| relative to other image layout transitions submitted to the same queue, |
| including those performed by <<renderpass, render passes>>. |
| In effect there is an implicit execution dependency from each such layout |
| transition to all layout transitions previously submitted to the same queue. |
| |
| ifdef::VK_EXT_sample_locations[] |
| |
| The image layout of each image subresource of a depth/stencil image created |
| with ename:VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT is |
| dependent on the last sample locations used to render to the image |
| subresource as a depth/stencil attachment, thus when the pname:image member |
| of an <<synchronization-image-memory-barriers, image memory barrier>> is an |
| image created with this flag the application can: chain a |
| slink:VkSampleLocationsInfoEXT structure to the pname:pNext chain of |
| ifdef::VK_KHR_synchronization2[] |
| slink:VkImageMemoryBarrier2KHR or |
| endif::VK_KHR_synchronization2[] |
| slink:VkImageMemoryBarrier to specify the sample locations to use during any |
| image layout transition. |
| |
| If the sname:VkSampleLocationsInfoEXT structure does not match the sample |
| location state last used to render to the image subresource range specified |
| by pname:subresourceRange, or if no sname:VkSampleLocationsInfoEXT structure |
| is present, then the contents of the given image subresource range becomes |
| undefined: as if pname:oldLayout would equal |
| ename:VK_IMAGE_LAYOUT_UNDEFINED. |
| |
| endif::VK_EXT_sample_locations[] |
| |
| |
| [[synchronization-pipeline-stages]] |
| === Pipeline Stages |
| |
| The work performed by an <<fundamentals-queueoperation-command-types, action |
| or synchronization command>> consists of multiple operations, which are |
| performed as a sequence of logically independent steps known as _pipeline |
| stages_. |
| The exact pipeline stages executed depend on the particular command that is |
| used, and current command buffer state when the command was recorded. |
| <<drawing,Drawing commands>>, <<dispatch,dispatching commands>>, |
| <<copies,copy commands>>, <<clears,clear commands>>, and <<synchronization, |
| synchronization commands>> all execute in different sets of |
| <<VkPipelineStageFlagBits,pipeline stages>>. |
| <<synchronization, Synchronization commands>> do not execute in a defined |
| pipeline stage. |
| |
| [NOTE] |
| .Note |
| ==== |
| Operations performed by synchronization commands (e.g. |
| <<synchronization-dependencies-available-and-visible, availability and |
| visibility operations>>) are not executed by a defined pipeline stage. |
| However other commands can still synchronize with them by using the |
| <<synchronization-dependencies-scopes, synchronization scopes>> to create a |
| <<synchronization-dependencies-chains, dependency chain>>. |
| ==== |
| |
| Execution of operations across pipeline stages must: adhere to |
| <<synchronization-implicit, implicit ordering guarantees>>, particularly |
| including <<synchronization-pipeline-stages-order, pipeline stage order>>. |
| Otherwise, execution across pipeline stages may: overlap or execute out of |
| order with regards to other stages, unless otherwise enforced by an |
| execution dependency. |
| |
| Several of the synchronization commands include pipeline stage parameters, |
| restricting the <<synchronization-dependencies-scopes, synchronization |
| scopes>> for that command to just those stages. |
| This allows fine grained control over the exact execution dependencies and |
| accesses performed by action commands. |
| Implementations should: use these pipeline stages to avoid unnecessary |
| stalls or cache flushing. |
| |
| ifdef::VK_KHR_synchronization2[] |
| [open,refpage='VkPipelineStageFlagBits2KHR',desc='Pipeline stage flags for VkPipelineStageFlags2KHR',type='enums'] |
| -- |
| Bits which can: be set in a tlink:VkPipelineStageFlags2KHR mask, specifying |
| stages of execution, are: |
| |
| ifdef::editing-notes[] |
| [NOTE] |
| .editing-note |
| ==== |
| The many places pipeline stage flags are used are not currently listed here. |
| ==== |
| endif::editing-notes[] |
| |
| include::{generated}/api/enums/VkPipelineStageFlagBits2KHR.txt[] |
| |
| * ename:VK_PIPELINE_STAGE_2_NONE_KHR specifies no stages of execution. |
| * ename:VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR specifies the stage of |
| the pipeline where indirect command parameters are consumed. |
| ifdef::VK_NV_device_generated_commands[] |
| This stage also includes reading commands written by |
| flink:vkCmdPreprocessGeneratedCommandsNV. |
| endif::VK_NV_device_generated_commands[] |
| ifdef::VK_NV_mesh_shader[] |
| * ename:VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV specifies the task shader |
| stage. |
| * ename:VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV specifies the mesh shader |
| stage. |
| endif::VK_NV_mesh_shader[] |
| * ename:VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR specifies the stage of the |
| pipeline where index buffers are consumed. |
| * ename:VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR specifies the |
| stage of the pipeline where vertex buffers are consumed. |
| * ename:VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR is equivalent to the |
| logical OR of: |
| ** ename:VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR |
| * ename:VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR specifies the vertex |
| shader stage. |
| * ename:VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR specifies |
| the tessellation control shader stage. |
| * ename:VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR |
| specifies the tessellation evaluation shader stage. |
| * ename:VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR specifies the geometry |
| shader stage. |
| * ename:VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR is |
| equivalent to specifying all supported |
| <<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stages>>: |
| ** ename:VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR |
| ifdef::VK_NV_mesh_shader[] |
| ** ename:VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV |
| ** ename:VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV |
| endif::VK_NV_mesh_shader[] |
| * ename:VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR specifies the fragment |
| shader stage. |
| * ename:VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR specifies the |
| stage of the pipeline where early fragment tests (depth and stencil |
| tests before fragment shading) are performed. |
| This stage also includes <<renderpass-load-store-ops, subpass load |
| operations>> for framebuffer attachments with a depth/stencil format. |
| * ename:VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR specifies the |
| stage of the pipeline where late fragment tests (depth and stencil tests |
| after fragment shading) are performed. |
| This stage also includes <<renderpass-load-store-ops, subpass store |
| operations>> for framebuffer attachments with a depth/stencil format. |
| * ename:VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR specifies the |
| stage of the pipeline after blending where the final color values are |
| output from the pipeline. |
| This stage also includes <<renderpass-load-store-ops, subpass load and |
| store operations>> and multisample resolve operations for framebuffer |
| attachments with a color |
| ifdef::VK_VERSION_1_2,VK_KHR_depth_stencil_resolve[] |
| or depth/stencil |
| endif::VK_VERSION_1_2,VK_KHR_depth_stencil_resolve[] |
| format. |
| * ename:VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR specifies the compute |
| shader stage. |
| * ename:VK_PIPELINE_STAGE_2_HOST_BIT_KHR specifies a pseudo-stage |
| indicating execution on the host of reads/writes of device memory. |
| This stage is not invoked by any commands recorded in a command buffer. |
| * ename:VK_PIPELINE_STAGE_2_COPY_BIT_KHR specifies the execution of all |
| <<copies,copy commands>>, including flink:vkCmdCopyQueryPoolResults. |
| * ename:VK_PIPELINE_STAGE_2_BLIT_BIT_KHR specifies the execution of |
| flink:vkCmdBlitImage. |
| * ename:VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR specifies the execution of |
| flink:vkCmdResolveImage. |
| * ename:VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR specifies the execution of |
| <<clears,clear commands>>, with the exception of |
| flink:vkCmdClearAttachments. |
| * ename:VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR is equivalent to |
| specifying all of: |
| ** ename:VK_PIPELINE_STAGE_2_COPY_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_BLIT_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR |
| ifdef::VK_KHR_ray_tracing_pipeline,VK_NV_ray_tracing[] |
| * ename:VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR specifies the |
| execution of the ray tracing shader stages. |
| endif::VK_KHR_ray_tracing_pipeline,VK_NV_ray_tracing[] |
| ifdef::VK_KHR_acceleration_structure,VK_NV_ray_tracing[] |
| * ename:VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR specifies |
| the execution of <<acceleration-structure, acceleration structure |
| commands>>. |
| endif::VK_KHR_acceleration_structure,VK_NV_ray_tracing[] |
| * ename:VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR specifies the execution |
| of all graphics pipeline stages, and is equivalent to the logical OR of: |
| ** ename:VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR |
| ifdef::VK_NV_mesh_shader[] |
| ** ename:VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV |
| ** ename:VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV |
| endif::VK_NV_mesh_shader[] |
| ** ename:VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR |
| ** ename:VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR |
| ifdef::VK_EXT_conditional_rendering[] |
| ** ename:VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT |
| endif::VK_EXT_conditional_rendering[] |
| ifdef::VK_EXT_transform_feedback[] |
| ** ename:VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT |
| endif::VK_EXT_transform_feedback[] |
| ifdef::VK_NV_shading_rate_image[] |
| ** ename:VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV |
| endif::VK_NV_shading_rate_image[] |
| ifdef::VK_EXT_fragment_density_map[] |
| ** ename:VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT |
| endif::VK_EXT_fragment_density_map[] |
| ifdef::VK_HUAWEI_invocation_mask[] |
| ** ename:VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI |
| endif::VK_HUAWEI_invocation_mask[] |
| * ename:VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR specifies all operations |
| performed by all commands supported on the queue it is used with. |
| ifdef::VK_EXT_conditional_rendering[] |
| * ename:VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT specifies the |
| stage of the pipeline where the predicate of conditional rendering is |
| consumed. |
| endif::VK_EXT_conditional_rendering[] |
| ifdef::VK_EXT_transform_feedback[] |
| * ename:VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT specifies the stage |
| of the pipeline where vertex attribute output values are written to the |
| transform feedback buffers. |
| endif::VK_EXT_transform_feedback[] |
| ifdef::VK_NV_device_generated_commands[] |
| * ename:VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV specifies the stage |
| of the pipeline where device-side generation of commands via |
| flink:vkCmdPreprocessGeneratedCommandsNV is handled. |
| endif::VK_NV_device_generated_commands[] |
| ifdef::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| * ename:VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
| specifies the stage of the pipeline where the |
| ifdef::VK_KHR_fragment_shading_rate[] |
| <<primsrast-fragment-shading-rate-attachment, fragment shading rate |
| attachment>> |
| endif::VK_KHR_fragment_shading_rate[] |
| ifdef::VK_KHR_fragment_shading_rate+VK_NV_shading_rate_image[or] |
| ifdef::VK_NV_shading_rate_image[] |
| <<primsrast-shading-rate-image, shading rate image>> |
| endif::VK_NV_shading_rate_image[] |
| is read to determine the fragment shading rate for portions of a |
| rasterized primitive. |
| endif::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| ifdef::VK_EXT_fragment_density_map[] |
| * ename:VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT specifies the |
| stage of the pipeline where the fragment density map is read to |
| <<fragmentdensitymapops,generate the fragment areas>>. |
| endif::VK_EXT_fragment_density_map[] |
| ifdef::VK_HUAWEI_invocation_mask[] |
| * ename:VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI specifies the stage |
| of the pipeline where the invocation mask image is read by the |
| implementation to optimize the ray dispatch. |
| endif::VK_HUAWEI_invocation_mask[] |
| ifdef::VK_KHR_video_decode_queue[] |
| * ename:VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR specifies the stage of |
| the pipeline where <<video-decode-operations, video decode operation>> |
| are performed. |
| endif::VK_KHR_video_decode_queue[] |
| ifdef::VK_KHR_video_encode_queue[] |
| * ename:VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR specifies the stage of |
| the pipeline where <<video-encode-operations, video encode operation>> |
| are performed. |
| endif::VK_KHR_video_encode_queue[] |
| ifdef::VK_HUAWEI_subpass_shading[] |
| * ename:VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI specifies the |
| subpass shading shader stage. |
| endif::VK_HUAWEI_subpass_shading[] |
| * ename:VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR is equivalent to |
| ename:VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR with |
| tlink:VkAccessFlags2KHR set to `0` when specified in the second |
| synchronization scope, but equivalent to |
| ename:VK_PIPELINE_STAGE_2_NONE_KHR in the first scope. |
| * ename:VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR is equivalent to |
| ename:VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR with |
| tlink:VkAccessFlags2KHR set to `0` when specified in the first |
| synchronization scope, but equivalent to |
| ename:VK_PIPELINE_STAGE_2_NONE_KHR in the second scope. |
| |
| [NOTE] |
| .Note |
| ==== |
| The etext:TOP and etext:BOTTOM pipeline stages are deprecated, and |
| applications should prefer ename:VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR |
| and ename:VK_PIPELINE_STAGE_2_NONE_KHR. |
| ==== |
| |
| [NOTE] |
| .Note |
| ==== |
| The tname:VkPipelineStageFlags2KHR bitmask goes beyond the 31 individual bit |
| flags allowable within a C99 enum, which is how |
| elink:VkPipelineStageFlagBits is defined. |
| The first 31 values are common to both, and are interchangeable. |
| ==== |
| -- |
| |
| [open,refpage='VkPipelineStageFlags2KHR',desc='64-bit mask of pipeline stage flags',type='flags'] |
| -- |
| tname:VkPipelineStageFlags2KHR is a bitmask type for setting a mask of zero |
| or more elink:VkPipelineStageFlagBits2KHR flags: |
| |
| include::{generated}/api/flags/VkPipelineStageFlags2KHR.txt[] |
| -- |
| endif::VK_KHR_synchronization2[] |
| |
| [open,refpage='VkPipelineStageFlagBits',desc='Bitmask specifying pipeline stages',type='enums'] |
| -- |
| Bits which can: be set in a tlink:VkPipelineStageFlags mask, specifying |
| stages of execution, are: |
| |
| include::{generated}/api/enums/VkPipelineStageFlagBits.txt[] |
| |
| ifdef::VK_KHR_synchronization2[] |
| These values all have the same meaning as the equivalently named values for |
| tlink:VkPipelineStageFlags2KHR. |
| endif::VK_KHR_synchronization2[] |
| |
| * ename:VK_PIPELINE_STAGE_NONE_KHR specifies no stages of execution. |
| * ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT specifies the stage of the |
| pipeline where stext:VkDrawIndirect* / stext:VkDispatchIndirect* / |
| stext:VkTraceRaysIndirect* data structures are consumed. |
| ifdef::VK_NV_device_generated_commands[] |
| This stage also includes reading commands written by |
| flink:vkCmdExecuteGeneratedCommandsNV. |
| endif::VK_NV_device_generated_commands[] |
| ifdef::VK_NV_mesh_shader[] |
| * ename:VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV specifies the task shader |
| stage. |
| * ename:VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV specifies the mesh shader |
| stage. |
| endif::VK_NV_mesh_shader[] |
| * ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT specifies the stage of the |
| pipeline where vertex and index buffers are consumed. |
| * ename:VK_PIPELINE_STAGE_VERTEX_SHADER_BIT specifies the vertex shader |
| stage. |
| * ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT specifies the |
| tessellation control shader stage. |
| * ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT specifies the |
| tessellation evaluation shader stage. |
| * ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT specifies the geometry |
| shader stage. |
| * ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT specifies the fragment |
| shader stage. |
| * ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT specifies the stage of |
| the pipeline where early fragment tests (depth and stencil tests before |
| fragment shading) are performed. |
| This stage also includes <<renderpass-load-store-ops, subpass load |
| operations>> for framebuffer attachments with a depth/stencil format. |
| * ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT specifies the stage of |
| the pipeline where late fragment tests (depth and stencil tests after |
| fragment shading) are performed. |
| This stage also includes <<renderpass-load-store-ops, subpass store |
| operations>> for framebuffer attachments with a depth/stencil format. |
| * ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT specifies the stage |
| of the pipeline after blending where the final color values are output |
| from the pipeline. |
| This stage also includes <<renderpass-load-store-ops, subpass load and |
| store operations>> and multisample resolve operations for framebuffer |
| attachments with a color |
| ifdef::VK_VERSION_1_2,VK_KHR_depth_stencil_resolve[] |
| or depth/stencil |
| endif::VK_VERSION_1_2,VK_KHR_depth_stencil_resolve[] |
| format. |
| * ename:VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT specifies the execution of a |
| compute shader. |
| * [[synchronization-pipeline-stages-transfer]] |
| ename:VK_PIPELINE_STAGE_TRANSFER_BIT specifies the following commands: |
| ** All <<copies,copy commands>>, including flink:vkCmdCopyQueryPoolResults |
| ifndef::VK_KHR_copy_commands2[] |
| ** flink:vkCmdBlitImage |
| ** flink:vkCmdResolveImage |
| endif::VK_KHR_copy_commands2[] |
| ifdef::VK_KHR_copy_commands2[] |
| ** flink:vkCmdBlitImage2KHR and flink:vkCmdBlitImage |
| ** flink:vkCmdResolveImage2KHR and flink:vkCmdResolveImage |
| endif::VK_KHR_copy_commands2[] |
| ** All <<clears,clear commands>>, with the exception of |
| flink:vkCmdClearAttachments |
| * ename:VK_PIPELINE_STAGE_HOST_BIT specifies a pseudo-stage indicating |
| execution on the host of reads/writes of device memory. |
| This stage is not invoked by any commands recorded in a command buffer. |
| ifdef::VK_NV_ray_tracing,VK_KHR_acceleration_structure[] |
| * ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR specifies |
| the execution of |
| ifdef::VK_NV_ray_tracing[] |
| flink:vkCmdBuildAccelerationStructureNV, |
| flink:vkCmdCopyAccelerationStructureNV, |
| flink:vkCmdWriteAccelerationStructuresPropertiesNV |
| endif::VK_NV_ray_tracing[] |
| ifdef::VK_NV_ray_tracing+VK_KHR_acceleration_structure[,] |
| ifdef::VK_KHR_acceleration_structure[] |
| flink:vkCmdBuildAccelerationStructuresKHR, |
| flink:vkCmdBuildAccelerationStructuresIndirectKHR, |
| flink:vkCmdCopyAccelerationStructureKHR, |
| flink:vkCmdCopyAccelerationStructureToMemoryKHR, |
| flink:vkCmdCopyMemoryToAccelerationStructureKHR, and |
| flink:vkCmdWriteAccelerationStructuresPropertiesKHR. |
| endif::VK_KHR_acceleration_structure[] |
| endif::VK_NV_ray_tracing,VK_KHR_acceleration_structure[] |
| ifdef::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| * ename:VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR specifies the |
| execution of the ray tracing shader stages, via |
| ifdef::VK_NV_ray_tracing[flink:vkCmdTraceRaysNV] |
| ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[,] |
| ifdef::VK_KHR_ray_tracing_pipeline[flink:vkCmdTraceRaysKHR, or flink:vkCmdTraceRaysIndirectKHR] |
| endif::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| * ename:VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT specifies the execution of all |
| graphics pipeline stages, and is equivalent to the logical OR of: |
| ** ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
| ifdef::VK_NV_mesh_shader[] |
| ** ename:VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV |
| ** ename:VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV |
| endif::VK_NV_mesh_shader[] |
| ** ename:VK_PIPELINE_STAGE_VERTEX_INPUT_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 |
| ** ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
| ** ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
| ** ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
| ifdef::VK_EXT_conditional_rendering[] |
| ** ename:VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT |
| endif::VK_EXT_conditional_rendering[] |
| ifdef::VK_EXT_transform_feedback[] |
| ** ename:VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT |
| endif::VK_EXT_transform_feedback[] |
| ifdef::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| ** ename:VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
| endif::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| ifdef::VK_EXT_fragment_density_map[] |
| ** ename:VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT |
| endif::VK_EXT_fragment_density_map[] |
| * ename:VK_PIPELINE_STAGE_ALL_COMMANDS_BIT specifies all operations |
| performed by all commands supported on the queue it is used with. |
| ifdef::VK_EXT_conditional_rendering[] |
| * ename:VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT specifies the |
| stage of the pipeline where the predicate of conditional rendering is |
| consumed. |
| endif::VK_EXT_conditional_rendering[] |
| ifdef::VK_EXT_transform_feedback[] |
| * ename:VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT specifies the stage |
| of the pipeline where vertex attribute output values are written to the |
| transform feedback buffers. |
| endif::VK_EXT_transform_feedback[] |
| ifdef::VK_NV_device_generated_commands[] |
| * ename:VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV specifies the stage of |
| the pipeline where device-side preprocessing for generated commands via |
| flink:vkCmdPreprocessGeneratedCommandsNV is handled. |
| endif::VK_NV_device_generated_commands[] |
| ifdef::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| * ename:VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
| specifies the stage of the pipeline where the |
| ifdef::VK_KHR_fragment_shading_rate[] |
| <<primsrast-fragment-shading-rate-attachment, fragment shading rate |
| attachment>> |
| endif::VK_KHR_fragment_shading_rate[] |
| ifdef::VK_KHR_fragment_shading_rate+VK_NV_shading_rate_image[or] |
| ifdef::VK_NV_shading_rate_image[] |
| <<primsrast-shading-rate-image, shading rate image>> |
| endif::VK_NV_shading_rate_image[] |
| is read to determine the fragment shading rate for portions of a |
| rasterized primitive. |
| endif::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| ifdef::VK_EXT_fragment_density_map[] |
| * ename:VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT specifies the |
| stage of the pipeline where the fragment density map is read to |
| <<fragmentdensitymapops,generate the fragment areas>>. |
| endif::VK_EXT_fragment_density_map[] |
| * ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT is equivalent to |
| ename:VK_PIPELINE_STAGE_ALL_COMMANDS_BIT with tlink:VkAccessFlags set to |
| `0` when specified in the second synchronization scope, but specifies no |
| stage of execution when specified in the first scope. |
| * ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT is equivalent to |
| ename:VK_PIPELINE_STAGE_ALL_COMMANDS_BIT with tlink:VkAccessFlags set to |
| `0` when specified in the first synchronization scope, but specifies no |
| stage of execution when specified in the second scope. |
| -- |
| |
| [open,refpage='VkPipelineStageFlags',desc='Bitmask of VkPipelineStageFlagBits',type='flags'] |
| -- |
| include::{generated}/api/flags/VkPipelineStageFlags.txt[] |
| |
| tname:VkPipelineStageFlags is a bitmask type for setting a mask of zero or |
| more elink:VkPipelineStageFlagBits. |
| -- |
| |
| [[synchronization-pipeline-stages-masks]] |
| If a synchronization command includes a source stage mask, its first |
| <<synchronization-dependencies-scopes, synchronization scope>> only includes |
| execution of the pipeline stages specified in that mask, and its first |
| <<synchronization-dependencies-access-scopes, access scope>> only includes |
| memory accesses performed by pipeline stages specified in that mask. |
| |
| If a synchronization command includes a destination stage mask, its second |
| <<synchronization-dependencies-scopes, synchronization scope>> only includes |
| execution of the pipeline stages specified in that mask, and its second |
| <<synchronization-dependencies-access-scopes, access scope>> only includes |
| memory access performed by pipeline stages specified in that mask. |
| |
| [NOTE] |
| .Note |
| ==== |
| Including a particular pipeline stage in the first |
| <<synchronization-dependencies-scopes, synchronization scope>> of a command |
| implicitly includes <<synchronization-pipeline-stages-order, logically |
| earlier>> pipeline stages in the synchronization scope. |
| Similarly, the second <<synchronization-dependencies-scopes, synchronization |
| scope>> includes <<synchronization-pipeline-stages-order, logically later>> |
| pipeline stages. |
| |
| However, note that <<synchronization-dependencies-access-scopes, access |
| scopes>> are not affected in this way - only the precise stages specified |
| are considered part of each access scope. |
| ==== |
| |
| Certain pipeline stages are only available on queues that support a |
| particular set of operations. |
| The following table lists, for each pipeline stage flag, which queue |
| capability flag must: be supported by the queue. |
| When multiple flags are enumerated in the second column of the table, it |
| means that the pipeline stage is supported on the queue if it supports any |
| of the listed capability flags. |
| For further details on queue capabilities see |
| <<devsandqueues-physical-device-enumeration,Physical Device Enumeration>> |
| and <<devsandqueues-queues,Queues>>. |
| |
| [[synchronization-pipeline-stages-supported]] |
| .Supported pipeline stage flags |
| [cols="60%,40%",options="header"] |
| |==== |
| |Pipeline stage flag | Required queue capability flag |
| |ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | None required |
| |ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | ename:VK_QUEUE_GRAPHICS_BIT or ename:VK_QUEUE_COMPUTE_BIT |
| |ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | ename:VK_QUEUE_GRAPHICS_BIT |
| |ename:VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | ename:VK_QUEUE_GRAPHICS_BIT |
| |ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | ename:VK_QUEUE_GRAPHICS_BIT |
| |ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | ename:VK_QUEUE_GRAPHICS_BIT |
| |ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | ename:VK_QUEUE_GRAPHICS_BIT |
| |ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | ename:VK_QUEUE_GRAPHICS_BIT |
| |ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | ename:VK_QUEUE_GRAPHICS_BIT |
| |ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | ename:VK_QUEUE_GRAPHICS_BIT |
| |ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | ename:VK_QUEUE_GRAPHICS_BIT |
| |ename:VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | ename:VK_QUEUE_COMPUTE_BIT |
| |ename:VK_PIPELINE_STAGE_TRANSFER_BIT | ename:VK_QUEUE_GRAPHICS_BIT, ename:VK_QUEUE_COMPUTE_BIT or ename:VK_QUEUE_TRANSFER_BIT |
| |ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT | None required |
| |ename:VK_PIPELINE_STAGE_HOST_BIT | None required |
| |ename:VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | ename:VK_QUEUE_GRAPHICS_BIT |
| |ename:VK_PIPELINE_STAGE_ALL_COMMANDS_BIT | None required |
| ifdef::VK_EXT_conditional_rendering[] |
| |ename:VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT | ename:VK_QUEUE_GRAPHICS_BIT or ename:VK_QUEUE_COMPUTE_BIT |
| endif::VK_EXT_conditional_rendering[] |
| ifdef::VK_EXT_transform_feedback[] |
| |ename:VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT | ename:VK_QUEUE_GRAPHICS_BIT |
| endif::VK_EXT_transform_feedback[] |
| ifdef::VK_NV_device_generated_commands[] |
| |ename:VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV | ename:VK_QUEUE_GRAPHICS_BIT or ename:VK_QUEUE_COMPUTE_BIT |
| endif::VK_NV_device_generated_commands[] |
| ifdef::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| |ename:VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR | ename:VK_QUEUE_GRAPHICS_BIT |
| endif::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| ifdef::VK_NV_mesh_shader[] |
| |ename:VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV | ename:VK_QUEUE_GRAPHICS_BIT |
| |ename:VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV | ename:VK_QUEUE_GRAPHICS_BIT |
| endif::VK_NV_mesh_shader[] |
| ifdef::VK_NV_ray_tracing,VK_KHR_acceleration_structure[] |
| |ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | ename:VK_QUEUE_COMPUTE_BIT |
| endif::VK_NV_ray_tracing,VK_KHR_acceleration_structure[] |
| ifdef::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| |ename:VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR | ename:VK_QUEUE_COMPUTE_BIT |
| endif::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| ifdef::VK_EXT_fragment_density_map[] |
| |ename:VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT | ename:VK_QUEUE_GRAPHICS_BIT |
| endif::VK_EXT_fragment_density_map[] |
| ifdef::VK_HUAWEI_subpass_shading[] |
| |ename:VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI | ename:VK_QUEUE_GRAPHICS_BIT |
| endif::VK_HUAWEI_subpass_shading[] |
| |==== |
| |
| [[synchronization-pipeline-stages-order]] |
| Pipeline stages that execute as a result of a command logically complete |
| execution in a specific order, such that completion of a logically later |
| pipeline stage must: not happen-before completion of a logically earlier |
| stage. |
| This means that including any stage in the source stage mask for a |
| particular synchronization command also implies that any logically earlier |
| stages are included in *A~S~* for that command. |
| |
| Similarly, initiation of a logically earlier pipeline stage must: not |
| happen-after initiation of a logically later pipeline stage. |
| Including any given stage in the destination stage mask for a particular |
| synchronization command also implies that any logically later stages are |
| included in *B~S~* for that command. |
| |
| [NOTE] |
| .Note |
| ==== |
| Implementations may: not support synchronization at every pipeline stage for |
| every synchronization operation. |
| If a pipeline stage that an implementation does not support synchronization |
| for appears in a source stage mask, it may: substitute any logically later |
| stage in its place for the first synchronization scope. |
| If a pipeline stage that an implementation does not support synchronization |
| for appears in a destination stage mask, it may: substitute any logically |
| earlier stage in its place for the second synchronization scope. |
| |
| For example, if an implementation is unable to signal an event immediately |
| after vertex shader execution is complete, it may: instead signal the event |
| after color attachment output has completed. |
| |
| If an implementation makes such a substitution, it must: not affect the |
| semantics of execution or memory dependencies or image and buffer memory |
| barriers. |
| ==== |
| |
| [[synchronization-pipeline-stages-types]][[synchronization-pipeline-graphics]] |
| <<pipelines-graphics, Graphics pipelines>> are executable on queues |
| supporting ename:VK_QUEUE_GRAPHICS_BIT. |
| Stages executed by graphics pipelines can: only be specified in commands |
| recorded for queues supporting ename:VK_QUEUE_GRAPHICS_BIT. |
| |
| The graphics |
| ifdef::VK_NV_mesh_shader[] |
| primitive |
| endif::VK_NV_mesh_shader[] |
| pipeline executes the following stages, with the logical ordering of the |
| stages matching the order specified here: |
| |
| * ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
| ifdef::VK_KHR_synchronization2[] |
| * ename:VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR |
| * ename:VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR |
| endif::VK_KHR_synchronization2[] |
| ifndef::VK_KHR_synchronization2[] |
| * ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
| endif::VK_KHR_synchronization2[] |
| * 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 |
| ifdef::VK_EXT_transform_feedback[] |
| * ename:VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT |
| endif::VK_EXT_transform_feedback[] |
| ifdef::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| * ename:VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
| endif::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| * ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
| * ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
| * ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
| * ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
| |
| ifdef::VK_NV_mesh_shader[] |
| The graphics mesh pipeline executes the following stages, with the logical |
| ordering of the stages matching the order specified here: |
| |
| * ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
| * ename:VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV |
| * ename:VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV |
| ifdef::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| * ename:VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
| endif::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| * ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
| * ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
| * ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
| * ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
| endif::VK_NV_mesh_shader[] |
| |
| For the compute pipeline, the following stages occur in this order: |
| |
| * ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
| * ename:VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
| |
| ifdef::VK_HUAWEI_subpass_shading[] |
| For the subpass shading pipeline, the following stages occur in this order: |
| |
| * ename:VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI |
| endif::VK_HUAWEI_subpass_shading[] |
| |
| ifdef::VK_EXT_fragment_density_map[] |
| For graphics pipeline commands executing in a render pass with a fragment |
| density map attachment, the following pipeline stage where the fragment |
| density map read happens has no particular order relative to the other |
| stages, except that it is logically earlier than |
| ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT: |
| |
| * ename:VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT |
| * ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
| endif::VK_EXT_fragment_density_map[] |
| |
| ifdef::VK_EXT_conditional_rendering[] |
| The conditional rendering stage is formally part of both the graphics, and |
| the compute pipeline. |
| The pipeline stage where the predicate read happens has unspecified order |
| relative to other stages of these pipelines: |
| |
| * ename:VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT |
| endif::VK_EXT_conditional_rendering[] |
| |
| For the transfer pipeline, the following stages occur in this order: |
| |
| * ename:VK_PIPELINE_STAGE_TRANSFER_BIT |
| |
| For host operations, only one pipeline stage occurs, so no order is |
| guaranteed: |
| |
| * ename:VK_PIPELINE_STAGE_HOST_BIT |
| |
| ifdef::VK_NV_device_generated_commands[] |
| For the command preprocessing pipeline, the following stages occur in this |
| order: |
| |
| * ename:VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV |
| endif::VK_NV_device_generated_commands[] |
| |
| ifdef::VK_NV_ray_tracing,VK_KHR_acceleration_structure[] |
| For acceleration structure operations, only one pipeline stage occurs, so no |
| order is guaranteed: |
| |
| * ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR |
| |
| endif::VK_NV_ray_tracing,VK_KHR_acceleration_structure[] |
| |
| ifdef::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| For the ray tracing pipeline, the following stages occur in this order: |
| |
| * ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
| * ename:VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR |
| |
| endif::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| |
| |
| [[synchronization-access-types]] |
| === Access Types |
| |
| Memory in Vulkan can: be accessed from within shader invocations and via |
| some fixed-function stages of the pipeline. |
| The _access type_ is a function of the <<descriptorsets, descriptor type>> |
| used, or how a fixed-function stage accesses memory. |
| |
| [[synchronization-access-masks]] |
| Some synchronization commands take sets of access types as parameters to |
| define the <<synchronization-dependencies-access-scopes, access scopes>> of |
| a memory dependency. |
| If a synchronization command includes a _source access mask_, its first |
| <<synchronization-dependencies-access-scopes, access scope>> only includes |
| accesses via the access types specified in that mask. |
| Similarly, if a synchronization command includes a _destination access |
| mask_, its second <<synchronization-dependencies-access-scopes, access |
| scope>> only includes accesses via the access types specified in that mask. |
| |
| ifdef::VK_KHR_synchronization2[] |
| [open,refpage='VkAccessFlagBits2KHR',desc='Access flags for VkAccessFlags2KHR',type='enums'] |
| -- |
| Bits which can: be set in the pname:srcAccessMask and pname:dstAccessMask |
| members of slink:VkMemoryBarrier2KHR, slink:VkImageMemoryBarrier2KHR, and |
| slink:VkBufferMemoryBarrier2KHR, specifying access behavior, are: |
| |
| include::{generated}/api/enums/VkAccessFlagBits2KHR.txt[] |
| |
| * ename:VK_ACCESS_2_NONE_KHR specifies no accesses. |
| * ename:VK_ACCESS_2_MEMORY_READ_BIT_KHR specifies all read accesses. |
| It is always valid in any access mask, and is treated as equivalent to |
| setting all etext:READ access flags that are valid where it is used. |
| * ename:VK_ACCESS_2_MEMORY_WRITE_BIT_KHR specifies all write accesses. |
| It is always valid in any access mask, and is treated as equivalent to |
| setting all etext:WRITE access flags that are valid where it is used. |
| * ename:VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR specifies read access to |
| command data read from indirect buffers as part of an indirect |
| ifdef::VK_KHR_acceleration_structure[build,] |
| ifdef::VK_KHR_ray_tracing_pipeline[trace,] |
| drawing or dispatch command. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR pipeline stage. |
| * ename:VK_ACCESS_2_INDEX_READ_BIT_KHR specifies read access to an index |
| buffer as part of an indexed drawing command, bound by |
| flink:vkCmdBindIndexBuffer. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR |
| pipeline stage. |
| * ename:VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR specifies read access to |
| a vertex buffer as part of a drawing command, bound by |
| flink:vkCmdBindVertexBuffers. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR pipeline stage. |
| * ename:VK_ACCESS_2_UNIFORM_READ_BIT_KHR specifies read access to a |
| <<descriptorsets-uniformbuffer, uniform buffer>> in any shader pipeline |
| stage. |
| * ename:VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR specifies read access to |
| an <<renderpass, input attachment>> within a render pass during |
| ifdef::VK_HUAWEI_subpass_shading[] |
| subpass shading or |
| endif::VK_HUAWEI_subpass_shading[] |
| fragment shading. |
| Such access occurs in the |
| ifdef::VK_HUAWEI_subpass_shading[] |
| ename:VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI or |
| endif::VK_HUAWEI_subpass_shading[] |
| ename:VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR pipeline stage. |
| * ename:VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR specifies read access to a |
| <<descriptorsets-uniformtexelbuffer, uniform texel buffer>> or |
| <<descriptorsets-sampledimage, sampled image>> in any shader pipeline |
| stage. |
| * ename:VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR specifies read access to a |
| <<descriptorsets-storagebuffer, storage buffer>>, |
| ifdef::VK_VERSION_1_2,VK_EXT_buffer_device_address,VK_buffer_device_address[] |
| <<descriptorsets-physical-storage-buffer, physical storage buffer>>, |
| endif::VK_VERSION_1_2,VK_EXT_buffer_device_address,VK_buffer_device_address[] |
| <<descriptorsets-storagetexelbuffer, storage texel buffer>>, or |
| <<descriptorsets-storageimage, storage image>> in any shader pipeline |
| stage. |
| * ename:VK_ACCESS_2_SHADER_READ_BIT_KHR |
| ifdef::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| specifies read access to a <<shader-binding-table, shader binding |
| table>> in any shader pipeline. |
| In addition, it |
| endif::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| is equivalent to the logical OR of: |
| ** ename:VK_ACCESS_2_UNIFORM_READ_BIT_KHR |
| ** ename:VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR |
| ** ename:VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR |
| * ename:VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR specifies write access to |
| a <<descriptorsets-storagebuffer, storage buffer>>, |
| ifdef::VK_VERSION_1_2,VK_EXT_buffer_device_address,VK_buffer_device_address[] |
| <<descriptorsets-physical-storage-buffer, physical storage buffer>>, |
| endif::VK_VERSION_1_2,VK_EXT_buffer_device_address,VK_buffer_device_address[] |
| <<descriptorsets-storagetexelbuffer, storage texel buffer>>, or |
| <<descriptorsets-storageimage, storage image>> in any shader pipeline |
| stage. |
| * ename:VK_ACCESS_2_SHADER_WRITE_BIT_KHR is equivalent to |
| ename:VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR. |
| * ename:VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR specifies read access to |
| a <<renderpass, color attachment>>, such as via <<framebuffer-blending, |
| blending>>, <<framebuffer-logicop, logic operations>>, or via certain |
| <<renderpass-load-store-ops, subpass load operations>>. |
| ifdef::VK_EXT_blend_operation_advanced[] |
| It does not include <<framebuffer-blend-advanced, advanced blend |
| operations>>. |
| endif::VK_EXT_blend_operation_advanced[] |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR pipeline |
| stage. |
| * ename:VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR specifies write access |
| to a |
| ifndef::VK_VERSION_1_2,VK_KHR_depth_stencil_resolve[] |
| <<renderpass, color or resolve attachment>> |
| endif::VK_VERSION_1_2,VK_KHR_depth_stencil_resolve[] |
| ifdef::VK_VERSION_1_2,VK_KHR_depth_stencil_resolve[] |
| <<renderpass, color, resolve, or depth/stencil resolve attachment>> |
| endif::VK_VERSION_1_2,VK_KHR_depth_stencil_resolve[] |
| during a <<renderpass, render pass>> or via certain |
| <<renderpass-load-store-ops, subpass load and store operations>>. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR pipeline |
| stage. |
| * ename:VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR specifies read |
| access to a <<renderpass, depth/stencil attachment>>, via |
| <<fragops-ds-state, depth or stencil operations>> or via certain |
| <<renderpass-load-store-ops, subpass load operations>>. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR or |
| ename:VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR pipeline stages. |
| * ename:VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR specifies write |
| access to a <<renderpass, depth/stencil attachment>>, via |
| <<fragops-ds-state, depth or stencil operations>> or via certain |
| <<renderpass-load-store-ops, subpass load and store operations>>. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR or |
| ename:VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR pipeline stages. |
| * ename:VK_ACCESS_2_TRANSFER_READ_BIT_KHR specifies read access to an |
| image or buffer in a <<copies, copy>> operation. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_2_COPY_BIT_KHR, |
| ename:VK_PIPELINE_STAGE_2_BLIT_BIT_KHR, or |
| ename:VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR pipeline stages. |
| * ename:VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR specifies write access to an |
| image or buffer in a <<clears, clear>> or <<copies, copy>> operation. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_2_COPY_BIT_KHR, |
| ename:VK_PIPELINE_STAGE_2_BLIT_BIT_KHR, |
| ename:VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR, or |
| ename:VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR pipeline stages. |
| * ename:VK_ACCESS_2_HOST_READ_BIT_KHR specifies read access by a host |
| operation. |
| Accesses of this type are not performed through a resource, but directly |
| on memory. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_2_HOST_BIT_KHR |
| pipeline stage. |
| * ename:VK_ACCESS_2_HOST_WRITE_BIT_KHR specifies write access by a host |
| operation. |
| Accesses of this type are not performed through a resource, but directly |
| on memory. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_2_HOST_BIT_KHR |
| pipeline stage. |
| ifdef::VK_EXT_conditional_rendering[] |
| * ename:VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT specifies read |
| access to a predicate as part of conditional rendering. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT pipeline stage. |
| endif::VK_EXT_conditional_rendering[] |
| ifdef::VK_EXT_transform_feedback[] |
| * ename:VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT specifies write |
| access to a transform feedback buffer made when transform feedback is |
| active. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT pipeline stage. |
| * ename:VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT specifies read |
| access to a transform feedback counter buffer which is read when |
| flink:vkCmdBeginTransformFeedbackEXT executes. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT pipeline stage. |
| * ename:VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT specifies |
| write access to a transform feedback counter buffer which is written |
| when flink:vkCmdEndTransformFeedbackEXT executes. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT pipeline stage. |
| endif::VK_EXT_transform_feedback[] |
| ifdef::VK_NV_device_generated_commands[] |
| * ename:VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV specifies reads from |
| buffer inputs to flink:vkCmdPreprocessGeneratedCommandsNV. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV pipeline stage. |
| * ename:VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV specifies writes to |
| the target command buffer preprocess outputs. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV pipeline stage. |
| endif::VK_NV_device_generated_commands[] |
| ifdef::VK_EXT_blend_operation_advanced[] |
| * ename:VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT specifies |
| read access to <<renderpass, color attachments>>, including |
| <<framebuffer-blend-advanced,advanced blend operations>>. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR pipeline |
| stage. |
| endif::VK_EXT_blend_operation_advanced[] |
| ifdef::VK_HUAWEI_invocation_mask[] |
| * ename:VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI specifies read access |
| to a invocation mask image in the |
| ename:VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI pipeline stage. |
| endif::VK_HUAWEI_invocation_mask[] |
| ifdef::VK_KHR_acceleration_structure,VK_NV_ray_tracing[] |
| * ename:VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR specifies read |
| access to an acceleration structure as part of a trace, build, or copy |
| command, or to an <<acceleration-structure-scratch, acceleration |
| structure scratch buffer>> as part of a build command. |
| Such access occurs in the |
| ifdef::VK_KHR_ray_tracing_pipeline[] |
| ename:VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR pipeline stage or |
| endif::VK_KHR_ray_tracing_pipeline[] |
| ename:VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR pipeline |
| stage. |
| * ename:VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR specifies write |
| access to an acceleration structure or <<acceleration-structure-scratch, |
| acceleration structure scratch buffer>> as part of a build or copy |
| command. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR pipeline |
| stage. |
| endif::VK_KHR_acceleration_structure,VK_NV_ray_tracing[] |
| ifdef::VK_EXT_fragment_density_map[] |
| * ename:VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT specifies read |
| access to a <<renderpass-fragmentdensitymapattachment, fragment density |
| map attachment>> during dynamic <<fragmentdensitymapops, fragment |
| density map operations>>. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT pipeline |
| stage. |
| endif::VK_EXT_fragment_density_map[] |
| ifdef::VK_KHR_fragment_shading_rate[] |
| * ename:VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR |
| specifies read access to a fragment shading rate attachment during |
| rasterization. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
| pipeline stage. |
| endif::VK_KHR_fragment_shading_rate[] |
| ifdef::VK_NV_shading_rate_image[] |
| * ename:VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV specifies read access |
| to a shading rate image during rasterization. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV pipeline stage. |
| ifdef::VK_KHR_fragment_shading_rate[] |
| It is equivalent to |
| ename:VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR. |
| endif::VK_KHR_fragment_shading_rate[] |
| endif::VK_NV_shading_rate_image[] |
| ifdef::VK_KHR_video_decode_queue[] |
| * ename:VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR specifies read access to an |
| image or buffer resource as part of a <<video-decode-operations, video |
| decode operation>>. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR |
| pipeline stage. |
| * ename:VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR specifies write access to |
| an image or buffer resource as part of a <<video-decode-operations, |
| video decode operation>>. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR |
| pipeline stage. |
| endif::VK_KHR_video_decode_queue[] |
| ifdef::VK_KHR_video_encode_queue[] |
| * ename:VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR specifies read access to an |
| image or buffer resource as part of a <<video-encode-operations, video |
| encode operation>>. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR |
| pipeline stage. |
| * ename:VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR specifies write access to |
| an image or buffer resource as part of a <<video-encode-operations, |
| video encode operation>>. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR |
| pipeline stage. |
| endif::VK_KHR_video_encode_queue[] |
| |
| [NOTE] |
| .Note |
| ==== |
| In situations where an application wishes to select all access types for a |
| given set of pipeline stages, ename:VK_ACCESS_2_MEMORY_READ_BIT_KHR or |
| ename:VK_ACCESS_2_MEMORY_WRITE_BIT_KHR can be used. |
| This is particularly useful when specifying stages that only have a single |
| access type. |
| ==== |
| |
| [NOTE] |
| .Note |
| ==== |
| The tname:VkAccessFlags2KHR bitmask goes beyond the 31 individual bit flags |
| allowable within a C99 enum, which is how elink:VkAccessFlagBits is defined. |
| The first 31 values are common to both, and are interchangeable. |
| ==== |
| -- |
| |
| [open,refpage='VkAccessFlags2KHR',desc='64-bit mask of access flags',type='flags'] |
| -- |
| tname:VkAccessFlags2KHR is a bitmask type for setting a mask of zero or more |
| elink:VkAccessFlagBits2KHR: |
| |
| include::{generated}/api/flags/VkAccessFlags2KHR.txt[] |
| -- |
| endif::VK_KHR_synchronization2[] |
| |
| [open,refpage='VkAccessFlagBits',desc='Bitmask specifying memory access types that will participate in a memory dependency',type='enums'] |
| -- |
| Bits which can: be set in the pname:srcAccessMask and pname:dstAccessMask |
| members of slink:VkSubpassDependency, |
| ifdef::VK_KHR_synchronization2[slink:VkSubpassDependency2,] |
| slink:VkMemoryBarrier, slink:VkBufferMemoryBarrier, and |
| slink:VkImageMemoryBarrier, specifying access behavior, are: |
| |
| include::{generated}/api/enums/VkAccessFlagBits.txt[] |
| |
| ifdef::VK_KHR_synchronization2[] |
| These values all have the same meaning as the equivalently named values for |
| tlink:VkAccessFlags2KHR. |
| |
| * ename:VK_ACCESS_NONE_KHR specifies no accesses. |
| endif::VK_KHR_synchronization2[] |
| * ename:VK_ACCESS_MEMORY_READ_BIT specifies all read accesses. |
| It is always valid in any access mask, and is treated as equivalent to |
| setting all etext:READ access flags that are valid where it is used. |
| * ename:VK_ACCESS_MEMORY_WRITE_BIT specifies all write accesses. |
| It is always valid in any access mask, and is treated as equivalent to |
| setting all etext:WRITE access flags that are valid where it is used. |
| * ename:VK_ACCESS_INDIRECT_COMMAND_READ_BIT specifies read access to |
| indirect command data read as part of an indirect |
| ifdef::VK_KHR_acceleration_structure[build,] |
| ifdef::VK_KHR_ray_tracing_pipeline[trace,] |
| drawing or dispatching command. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
| pipeline stage. |
| * ename:VK_ACCESS_INDEX_READ_BIT specifies read access to an index buffer |
| as part of an indexed drawing command, bound by |
| flink:vkCmdBindIndexBuffer. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
| pipeline stage. |
| * ename:VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT specifies read access to a |
| vertex buffer as part of a drawing command, bound by |
| flink:vkCmdBindVertexBuffers. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
| pipeline stage. |
| * ename:VK_ACCESS_UNIFORM_READ_BIT specifies read access to a |
| <<descriptorsets-uniformbuffer, uniform buffer>> in any shader pipeline |
| stage. |
| * ename:VK_ACCESS_INPUT_ATTACHMENT_READ_BIT specifies read access to an |
| <<renderpass, input attachment>> within a render pass during |
| ifdef::VK_HUAWEI_subpass_shading[] |
| subpass shading or |
| endif::VK_HUAWEI_subpass_shading[] |
| fragment shading. |
| Such access occurs in the |
| ifdef::VK_HUAWEI_subpass_shading[] |
| ename:VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI or |
| endif::VK_HUAWEI_subpass_shading[] |
| ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT pipeline stage. |
| * ename:VK_ACCESS_SHADER_READ_BIT specifies read access to a |
| <<descriptorsets-uniformbuffer, uniform buffer>>, |
| <<descriptorsets-uniformtexelbuffer, uniform texel buffer>>, |
| <<descriptorsets-sampledimage, sampled image>>, |
| <<descriptorsets-storagebuffer, storage buffer>>, |
| ifdef::VK_VERSION_1_2,VK_EXT_buffer_device_address,VK_KHR_buffer_device_address[] |
| <<descriptorsets-physical-storage-buffer, physical storage buffer>>, |
| endif::VK_VERSION_1_2,VK_EXT_buffer_device_address,VK_KHR_buffer_device_address[] |
| ifdef::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| <<shader-binding-table, shader binding table>>, |
| endif::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| <<descriptorsets-storagetexelbuffer, storage texel buffer>>, or |
| <<descriptorsets-storageimage, storage image>> in any shader pipeline |
| stage. |
| * ename:VK_ACCESS_SHADER_WRITE_BIT specifies write access to a |
| <<descriptorsets-storagebuffer, storage buffer>>, |
| ifdef::VK_VERSION_1_2,VK_EXT_buffer_device_address,VK_KHR_buffer_device_address[] |
| <<descriptorsets-physical-storage-buffer, physical storage buffer>>, |
| endif::VK_VERSION_1_2,VK_EXT_buffer_device_address,VK_KHR_buffer_device_address[] |
| <<descriptorsets-storagetexelbuffer, storage texel buffer>>, or |
| <<descriptorsets-storageimage, storage image>> in any shader pipeline |
| stage. |
| * ename:VK_ACCESS_COLOR_ATTACHMENT_READ_BIT specifies read access to a |
| <<renderpass, color attachment>>, such as via <<framebuffer-blending, |
| blending>>, <<framebuffer-logicop, logic operations>>, or via certain |
| <<renderpass-load-store-ops, subpass load operations>>. |
| ifdef::VK_EXT_blend_operation_advanced[] |
| It does not include <<framebuffer-blend-advanced, advanced blend |
| operations>>. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage. |
| endif::VK_EXT_blend_operation_advanced[] |
| * ename:VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT specifies write access to a |
| ifndef::VK_VERSION_1_2,VK_KHR_depth_stencil_resolve[] |
| <<renderpass, color or resolve attachment>> |
| endif::VK_VERSION_1_2,VK_KHR_depth_stencil_resolve[] |
| ifdef::VK_VERSION_1_2,VK_KHR_depth_stencil_resolve[] |
| <<renderpass, color, resolve, or depth/stencil resolve attachment>> |
| endif::VK_VERSION_1_2,VK_KHR_depth_stencil_resolve[] |
| during a <<renderpass, render pass>> or via certain |
| <<renderpass-load-store-ops, subpass load and store operations>>. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage. |
| * ename:VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT specifies read access |
| to a <<renderpass, depth/stencil attachment>>, via <<fragops-ds-state, |
| depth or stencil operations>> or via certain |
| <<renderpass-load-store-ops, subpass load operations>>. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT or |
| ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT pipeline stages. |
| * ename:VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT specifies write |
| access to a <<renderpass, depth/stencil attachment>>, via |
| <<fragops-ds-state, depth or stencil operations>> or via certain |
| <<renderpass-load-store-ops, subpass load and store operations>>. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT or |
| ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT pipeline stages. |
| * ename:VK_ACCESS_TRANSFER_READ_BIT specifies read access to an image or |
| buffer in a <<copies, copy>> operation. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR |
| pipeline stage. |
| * ename:VK_ACCESS_TRANSFER_WRITE_BIT specifies write access to an image or |
| buffer in a <<clears, clear>> or <<copies, copy>> operation. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR |
| pipeline stage. |
| * ename:VK_ACCESS_HOST_READ_BIT specifies read access by a host operation. |
| Accesses of this type are not performed through a resource, but directly |
| on memory. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_HOST_BIT pipeline |
| stage. |
| * ename:VK_ACCESS_HOST_WRITE_BIT specifies write access by a host |
| operation. |
| Accesses of this type are not performed through a resource, but directly |
| on memory. |
| Such access occurs in the ename:VK_PIPELINE_STAGE_HOST_BIT pipeline |
| stage. |
| ifdef::VK_EXT_conditional_rendering[] |
| * ename:VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT specifies read access |
| to a predicate as part of conditional rendering. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT pipeline stage. |
| endif::VK_EXT_conditional_rendering[] |
| ifdef::VK_EXT_transform_feedback[] |
| * ename:VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT specifies write access |
| to a transform feedback buffer made when transform feedback is active. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT pipeline stage. |
| * ename:VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT specifies read |
| access to a transform feedback counter buffer which is read when |
| fname:vkCmdBeginTransformFeedbackEXT executes. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT pipeline stage. |
| * ename:VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT specifies write |
| access to a transform feedback counter buffer which is written when |
| fname:vkCmdEndTransformFeedbackEXT executes. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT pipeline stage. |
| endif::VK_EXT_transform_feedback[] |
| ifdef::VK_NV_device_generated_commands[] |
| * ename:VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV specifies reads from |
| buffer inputs to flink:vkCmdPreprocessGeneratedCommandsNV. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV pipeline stage. |
| * ename:VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV specifies writes to the |
| target command buffer:VkBuffer preprocess outputs in |
| flink:vkCmdPreprocessGeneratedCommandsNV. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV pipeline stage. |
| endif::VK_NV_device_generated_commands[] |
| ifdef::VK_EXT_blend_operation_advanced[] |
| * ename:VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT specifies read |
| access to <<renderpass, color attachments>>, including |
| <<framebuffer-blend-advanced,advanced blend operations>>. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage. |
| endif::VK_EXT_blend_operation_advanced[] |
| ifdef::VK_KHR_acceleration_structure,VK_NV_ray_tracing[] |
| ifdef::VK_HUAWEI_invocation_mask[] |
| * ename:VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI specifies read access |
| to a invocation mask image in the |
| ename:VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI pipeline stage. |
| endif::VK_HUAWEI_invocation_mask[] |
| * ename:VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR specifies read |
| access to an acceleration structure as part of a trace, build, or copy |
| command, or to an <<acceleration-structure-scratch, acceleration |
| structure scratch buffer>> as part of a build command. |
| Such access occurs in the |
| ifdef::VK_KHR_ray_tracing_pipeline[] |
| ename:VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR pipeline stage or |
| endif::VK_KHR_ray_tracing_pipeline[] |
| ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR pipeline |
| stage. |
| * ename:VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR specifies write |
| access to an acceleration structure or <<acceleration-structure-scratch, |
| acceleration structure scratch buffer>> as part of a build or copy |
| command. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR pipeline |
| stage. |
| endif::VK_KHR_acceleration_structure,VK_NV_ray_tracing[] |
| ifdef::VK_EXT_fragment_density_map[] |
| * ename:VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT specifies read access |
| to a <<renderpass-fragmentdensitymapattachment, fragment density map |
| attachment>> during dynamic <<fragmentdensitymapops, fragment density |
| map operations>> Such access occurs in the |
| ename:VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT pipeline stage. |
| endif::VK_EXT_fragment_density_map[] |
| ifdef::VK_KHR_fragment_shading_rate[] |
| * ename:VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR specifies |
| read access to a fragment shading rate attachment during rasterization. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
| pipeline stage. |
| endif::VK_KHR_fragment_shading_rate[] |
| ifdef::VK_NV_shading_rate_image[] |
| * ename:VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV specifies read access to |
| a shading rate image during rasterization. |
| Such access occurs in the |
| ename:VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV pipeline stage. |
| ifdef::VK_KHR_fragment_shading_rate[] |
| It is equivalent to |
| ename:VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR. |
| endif::VK_KHR_fragment_shading_rate[] |
| endif::VK_NV_shading_rate_image[] |
| |
| Certain access types are only performed by a subset of pipeline stages. |
| Any synchronization command that takes both stage masks and access masks |
| uses both to define the <<synchronization-dependencies-access-scopes, access |
| scopes>> - only the specified access types performed by the specified stages |
| are included in the access scope. |
| An application must: not specify an access flag in a synchronization command |
| if it does not include a pipeline stage in the corresponding stage mask that |
| is able to perform accesses of that type. |
| The following table lists, for each access flag, which pipeline stages can: |
| perform that type of access. |
| |
| [[synchronization-access-types-supported]] |
| .Supported access types |
| [cols="50,50",options="header"] |
| |==== |
| |Access flag | Supported pipeline stages |
| |ename:VK_ACCESS_INDIRECT_COMMAND_READ_BIT | ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
| ifdef::VK_KHR_acceleration_structure[] |
| , ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR |
| endif::VK_KHR_acceleration_structure[] |
| |ename:VK_ACCESS_INDEX_READ_BIT | ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
| |ename:VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
| |
| |ename:VK_ACCESS_UNIFORM_READ_BIT | |
| ifdef::VK_NV_mesh_shader[] |
| ename:VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, ename:VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, |
| endif::VK_NV_mesh_shader[] |
| ifdef::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| ename:VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, |
| endif::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| 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 |
| |
| |ename:VK_ACCESS_SHADER_READ_BIT | |
| ifdef::VK_KHR_acceleration_structure[] |
| ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, |
| endif::VK_KHR_acceleration_structure[] |
| ifdef::VK_NV_mesh_shader[] |
| ename:VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, ename:VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, |
| endif::VK_NV_mesh_shader[] |
| ifdef::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| ename:VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, |
| endif::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| 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 |
| |
| |ename:VK_ACCESS_SHADER_WRITE_BIT | |
| ifdef::VK_NV_mesh_shader[] |
| ename:VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, ename:VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, |
| endif::VK_NV_mesh_shader[] |
| ifdef::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| ename:VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, |
| endif::VK_NV_ray_tracing,VK_KHR_ray_tracing_pipeline[] |
| 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 |
| |
| |ename:VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | |
| ifdef::VK_HUAWEI_subpass_shading[] |
| ename:VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI, or |
| endif::VK_HUAWEI_subpass_shading[] |
| ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
| |ename:VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
| |ename:VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
| |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 |
| |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 |
| |ename:VK_ACCESS_TRANSFER_READ_BIT | ename:VK_PIPELINE_STAGE_TRANSFER_BIT |
| ifdef::VK_KHR_acceleration_structure[or ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR] |
| |ename:VK_ACCESS_TRANSFER_WRITE_BIT | ename:VK_PIPELINE_STAGE_TRANSFER_BIT |
| ifdef::VK_KHR_acceleration_structure[or ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR] |
| |ename:VK_ACCESS_HOST_READ_BIT | ename:VK_PIPELINE_STAGE_HOST_BIT |
| |ename:VK_ACCESS_HOST_WRITE_BIT | ename:VK_PIPELINE_STAGE_HOST_BIT |
| |ename:VK_ACCESS_MEMORY_READ_BIT | Any |
| |ename:VK_ACCESS_MEMORY_WRITE_BIT | Any |
| ifdef::VK_EXT_blend_operation_advanced[] |
| |ename:VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT | ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
| endif::VK_EXT_blend_operation_advanced[] |
| ifdef::VK_NV_device_generated_commands[] |
| |ename:VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV | ename:VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV |
| |ename:VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV | ename:VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV |
| endif::VK_NV_device_generated_commands[] |
| ifdef::VK_EXT_conditional_rendering[] |
| |ename:VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT | ename:VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT |
| endif::VK_EXT_conditional_rendering[] |
| ifdef::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| |ename:VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR | ename:VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
| endif::VK_KHR_fragment_shading_rate,VK_NV_shading_rate_image[] |
| ifdef::VK_HUAWEI_invocation_mask[] |
| |ename:VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI | ename:VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI |
| endif::VK_HUAWEI_invocation_mask[] |
| ifdef::VK_EXT_transform_feedback[] |
| |ename:VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT | ename:VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT |
| |ename:VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT | ename:VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT |
| |ename:VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT | ename:VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
| endif::VK_EXT_transform_feedback[] |
| ifdef::VK_NV_ray_tracing,VK_KHR_acceleration_structure[] |
| |ename:VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | |
| ifdef::VK_KHR_ray_query[] |
| ifdef::VK_NV_mesh_shader[] |
| ename:VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, ename:VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, |
| endif::VK_NV_mesh_shader[] |
| 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, ename:VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, |
| endif::VK_KHR_ray_query[] |
| ifdef::VK_KHR_ray_tracing_pipeline[] |
| ename:VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, |
| endif::VK_KHR_ray_tracing_pipeline[] |
| ifdef::VK_KHR_ray_tracing_pipeline,VK_KHR_ray_query[] |
| or |
| endif::VK_KHR_ray_tracing_pipeline,VK_KHR_ray_query[] |
| ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR |
| |ename:VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | ename:VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR |
| endif::VK_NV_ray_tracing,VK_KHR_acceleration_structure[] |
| ifdef::VK_EXT_fragment_density_map[] |
| |ename:VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT | ename:VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT |
| endif::VK_EXT_fragment_density_map[] |
| |==== |
| -- |
| |
| [open,refpage='VkAccessFlags',desc='Bitmask of VkAccessFlagBits',type='flags'] |
| -- |
| include::{generated}/api/flags/VkAccessFlags.txt[] |
| |
| tname:VkAccessFlags is a bitmask type for setting a mask of zero or more |
| elink:VkAccessFlagBits. |
| -- |
| |
| |
| [[synchronization-host-access-types]] |
| If a memory object does not have the |
| ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT property, then |
| flink:vkFlushMappedMemoryRanges must: be called in order to guarantee that |
| writes to the memory object from the host are made available to the host |
| domain, where they can: be further made available to the device domain via a |
| domain operation. |
| Similarly, flink:vkInvalidateMappedMemoryRanges must: be called to guarantee |
| that writes which are available to the host domain are made visible to host |
| operations. |
| |
| If the memory object does have the |
| ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT property flag, writes to the |
| memory object from the host are automatically made available to the host |
| domain. |
| Similarly, writes made available to the host domain are automatically made |
| visible to the host. |
| |
| [NOTE] |
| .Note |
| ==== |
| <<devsandqueues-submission, Queue submission commands>> automatically |
| perform a <<synchronization-submission-host-writes,domain operation from |
| host to device>> for all writes performed before the command executes, so in |
| most cases an explicit memory barrier is not needed for this case. |
| In the few circumstances where a submit does not occur between the host |
| write and the device read access, writes can: be made available by using an |
| explicit memory barrier. |
| ==== |
| |
| |
| [[synchronization-framebuffer-regions]] |
| === Framebuffer Region Dependencies |
| |
| <<synchronization-pipeline-stages, Pipeline stages>> that operate on, or |
| with respect to, the framebuffer are collectively the _framebuffer-space_ |
| pipeline stages. |
| These stages are: |
| |
| * ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
| * ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
| * ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
| * ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
| |
| For these pipeline stages, an execution or memory dependency from the first |
| set of operations to the second set can: either be a single |
| _framebuffer-global_ dependency, or split into multiple _framebuffer-local_ |
| dependencies. |
| A dependency with non-framebuffer-space pipeline stages is neither |
| framebuffer-global nor framebuffer-local. |
| |
| ifndef::VK_QCOM_render_pass_shader_resolve[] |
| A _framebuffer region_ is a set of sample (x, y, layer, sample) coordinates |
| that is a subset of the entire framebuffer. |
| endif::VK_QCOM_render_pass_shader_resolve[] |
| ifdef::VK_QCOM_render_pass_shader_resolve[] |
| A _framebuffer region_ is a subset of the entire framebuffer, and can: |
| either be: |
| |
| * A _sample region_, which is set of sample (x, y, layer, sample) |
| coordinates that is a subset of the entire framebuffer, or |
| |
| * A _fragment region_, which is a set of fragment (x, y, layer) coordinates |
| that is a subset of the entire framebuffer. |
| endif::VK_QCOM_render_pass_shader_resolve[] |
| |
| Both <<synchronization-dependencies-scopes, synchronization scopes>> of a |
| framebuffer-local dependency include only the operations performed within |
| corresponding framebuffer regions (as defined below). |
| No ordering guarantees are made between different framebuffer regions for a |
| framebuffer-local dependency. |
| |
| Both <<synchronization-dependencies-scopes, synchronization scopes>> of a |
| framebuffer-global dependency include operations on all framebuffer-regions. |
| |
| If the first synchronization scope includes operations on pixels/fragments |
| with N samples and the second synchronization scope includes operations on |
| pixels/fragments with M samples, where N does not equal M, then a |
| framebuffer region containing all samples at a given (x, y, layer) |
| coordinate in the first synchronization scope corresponds to a region |
| containing all samples at the same coordinate in the second synchronization |
| scope. |
| ifndef::VK_QCOM_render_pass_shader_resolve[] |
| In other words, it is a pixel granularity dependency. |
| endif::VK_QCOM_render_pass_shader_resolve[] |
| ifdef::VK_QCOM_render_pass_shader_resolve[] |
| In other words, the framebuffer region is a fragment region and it is a |
| pixel granularity dependency. |
| endif::VK_QCOM_render_pass_shader_resolve[] |
| If N equals M, |
| ifdef::VK_QCOM_render_pass_shader_resolve[] |
| and if the sname:VkSubpassDescription::pname:flags does not specify the |
| ename:VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM flag, |
| endif::VK_QCOM_render_pass_shader_resolve[] |
| then a framebuffer region containing a single (x, y, layer, sample) |
| coordinate in the first synchronization scope corresponds to a region |
| containing the same sample at the same coordinate in the second |
| synchronization scope. |
| ifndef::VK_QCOM_render_pass_shader_resolve[] |
| In other words, it is a sample granularity dependency. |
| endif::VK_QCOM_render_pass_shader_resolve[] |
| ifdef::VK_QCOM_render_pass_shader_resolve[] |
| In other words, the framebuffer region is a sample region and it is a sample |
| granularity dependency. |
| endif::VK_QCOM_render_pass_shader_resolve[] |
| |
| [NOTE] |
| .Note |
| ==== |
| Since fragment shader invocations are not specified to run in any particular |
| groupings, the size of a framebuffer region is implementation-dependent, not |
| known to the application, and must: be assumed to be no larger than |
| specified above. |
| ==== |
| |
| [NOTE] |
| .Note |
| ==== |
| Practically, the pixel vs sample granularity dependency means that if an |
| input attachment has a different number of samples than the pipeline's |
| pname:rasterizationSamples, then a fragment can: access any sample in the |
| input attachment's pixel even if it only uses framebuffer-local |
| dependencies. |
| If the input attachment has the same number of samples, then the fragment |
| can: only access the covered samples in its input code:SampleMask (i.e. the |
| fragment operations happen-after a framebuffer-local dependency for each |
| sample the fragment covers). |
| To access samples that are not covered, |
| ifdef::VK_QCOM_render_pass_shader_resolve[] |
| either the sname:VkSubpassDescription::pname:flags |
| ename:VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM flag is required, or |
| endif::VK_QCOM_render_pass_shader_resolve[] |
| a framebuffer-global dependency is required. |
| ==== |
| |
| If a synchronization command includes a pname:dependencyFlags parameter, and |
| specifies the ename:VK_DEPENDENCY_BY_REGION_BIT flag, then it defines |
| framebuffer-local dependencies for the framebuffer-space pipeline stages in |
| that synchronization command, for all framebuffer regions. |
| If no pname:dependencyFlags parameter is included, or the |
| ename:VK_DEPENDENCY_BY_REGION_BIT flag is not specified, then a |
| framebuffer-global dependency is specified for those stages. |
| The ename:VK_DEPENDENCY_BY_REGION_BIT flag does not affect the dependencies |
| between non-framebuffer-space pipeline stages, nor does it affect the |
| dependencies between framebuffer-space and non-framebuffer-space pipeline |
| stages. |
| |
| [NOTE] |
| .Note |
| ==== |
| Framebuffer-local dependencies are more efficient for most architectures; |
| particularly tile-based architectures - which can keep framebuffer-regions |
| entirely in on-chip registers and thus avoid external bandwidth across such |
| a dependency. |
| Including a framebuffer-global dependency in your rendering will usually |
| force all implementations to flush data to memory, or to a higher level |
| cache, breaking any potential locality optimizations. |
| ==== |
| |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_multiview[] |
| [[synchronization-view-local-dependencies]] |
| === View-Local Dependencies |
| |
| In a render pass instance that has <<renderpass-multiview,multiview>> |
| enabled, dependencies can: be either view-local or view-global. |
| |
| A view-local dependency only includes operations from a single |
| <<renderpass-multiview-view-local,source view>> from the source subpass in |
| the first synchronization scope, and only includes operations from a single |
| <<renderpass-multiview-view-local,destination view>> from the destination |
| subpass in the second synchronization scope. |
| A view-global dependency includes all views in the view mask of the source |
| and destination subpasses in the corresponding synchronization scopes. |
| |
| If a synchronization command includes a pname:dependencyFlags parameter and |
| specifies the ename:VK_DEPENDENCY_VIEW_LOCAL_BIT flag, then it defines |
| view-local dependencies for that synchronization command, for all views. |
| If no pname:dependencyFlags parameter is included or the |
| ename:VK_DEPENDENCY_VIEW_LOCAL_BIT flag is not specified, then a view-global |
| dependency is specified. |
| endif::VK_VERSION_1_1,VK_KHR_multiview[] |
| |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_device_group[] |
| [[synchronization-device-local-dependencies]] |
| === Device-Local Dependencies |
| |
| Dependencies can: be either device-local or non-device-local. |
| A device-local dependency acts as multiple separate dependencies, one for |
| each physical device that executes the synchronization command, where each |
| dependency only includes operations from that physical device in both |
| synchronization scopes. |
| A non-device-local dependency is a single dependency where both |
| synchronization scopes include operations from all physical devices that |
| participate in the synchronization command. |
| For subpass dependencies, all physical devices in the |
| slink:VkDeviceGroupRenderPassBeginInfo::pname:deviceMask participate in the |
| dependency, and for pipeline barriers all physical devices that are set in |
| the command buffer's current device mask participate in the dependency. |
| |
| If a synchronization command includes a pname:dependencyFlags parameter and |
| specifies the ename:VK_DEPENDENCY_DEVICE_GROUP_BIT flag, then it defines a |
| non-device-local dependency for that synchronization command. |
| If no pname:dependencyFlags parameter is included or the |
| ename:VK_DEPENDENCY_DEVICE_GROUP_BIT flag is not specified, then it defines |
| device-local dependencies for that synchronization command, for all |
| participating physical devices. |
| |
| Semaphore and event dependencies are device-local and only execute on the |
| one physical device that performs the dependency. |
| endif::VK_VERSION_1_1,VK_KHR_device_group[] |
| |
| |
| [[synchronization-implicit]] |
| == Implicit Synchronization Guarantees |
| |
| A small number of implicit ordering guarantees are provided by Vulkan, |
| ensuring that the order in which commands are submitted is meaningful, and |
| avoiding unnecessary complexity in common operations. |
| |
| [[synchronization-submission-order]] |
| _Submission order_ is a fundamental ordering in Vulkan, giving meaning to |
| the order in which <<fundamentals-queueoperation-command-types, action and |
| synchronization commands>> are recorded and submitted to a single queue. |
| Explicit and implicit ordering guarantees between commands in Vulkan all |
| work on the premise that this ordering is meaningful. |
| This order does not itself define any execution or memory dependencies; |
| synchronization commands and other orderings within the API use this |
| ordering to define their scopes. |
| |
| Submission order for any given set of commands is based on the order in |
| which they were recorded to command buffers and then submitted. |
| This order is determined as follows: |
| |
| . The initial order is determined by the order in which |
| flink:vkQueueSubmit |
| ifdef::VK_KHR_synchronization2[] |
| and flink:vkQueueSubmit2KHR |
| endif::VK_KHR_synchronization2[] |
| commands are executed on the host, for a single queue, from first to |
| last. |
| . The order in which slink:VkSubmitInfo structures are specified in the |
| pname:pSubmits parameter of flink:vkQueueSubmit, |
| ifdef::VK_KHR_synchronization2[] |
| or in which slink:VkSubmitInfo2KHR structures are specified in the |
| pname:pSubmits parameter of flink:vkQueueSubmit2KHR, |
| endif::VK_KHR_synchronization2[] |
| from lowest index to highest. |
| . The order in which command buffers are specified in the |
| pname:pCommandBuffers member of slink:VkSubmitInfo |
| ifdef::VK_KHR_synchronization2[] |
| or slink:VkSubmitInfo2KHR |
| endif::VK_KHR_synchronization2[] |
| from lowest index to highest. |
| . The order in which commands were recorded to a command buffer on the |
| host, from first to last: |
| ** For commands recorded outside a render pass, this includes all other |
| commands recorded outside a render pass, including |
| flink:vkCmdBeginRenderPass and flink:vkCmdEndRenderPass commands; it |
| does not directly include commands inside a render pass. |
| ** For commands recorded inside a render pass, this includes all other |
| commands recorded inside the same subpass, including the |
| flink:vkCmdBeginRenderPass and flink:vkCmdEndRenderPass commands that |
| delimit the same render pass instance; it does not include commands |
| recorded to other subpasses. |
| <<fundamentals-queueoperation-command-types, State commands>> do not execute |
| any operations on the device, instead they set the state of the command |
| buffer when they execute on the host, in the order that they are recorded. |
| <<fundamentals-queueoperation-command-types, Action commands>> consume the |
| current state of the command buffer when they are recorded, and will execute |
| state changes on the device as required to match the recorded state. |
| |
| <<queries-order, Query commands>>, <<drawing-primitive-order, the order of |
| primitives passing through the graphics pipeline>> and |
| <<synchronization-image-barrier-layout-transition-order, image layout |
| transitions as part of an image memory barrier>> provide additional |
| guarantees based on submission order. |
| |
| Execution of <<synchronization-pipeline-stages-order, pipeline stages>> |
| within a given command also has a loose ordering, dependent only on a single |
| command. |
| |
| [[synchronization-signal-operation-order]] |
| _Signal operation order_ is a fundamental ordering in Vulkan, giving meaning |
| to the order in which semaphore and fence signal operations occur when |
| submitted to a single queue. |
| The signal operation order for queue operations is determined as follows: |
| |
| . The initial order is determined by the order in which |
| flink:vkQueueSubmit |
| ifdef::VK_KHR_synchronization2[] |
| and flink:vkQueueSubmit2KHR |
| endif::VK_KHR_synchronization2[] |
| commands are executed on the host, for a single queue, from first to |
| last. |
| . The order in which slink:VkSubmitInfo structures are specified in the |
| pname:pSubmits parameter of flink:vkQueueSubmit, |
| ifdef::VK_KHR_synchronization2[] |
| or in which slink:VkSubmitInfo2KHR structures are specified in the |
| pname:pSubmits parameter of flink:vkQueueSubmit2KHR, |
| endif::VK_KHR_synchronization2[] |
| from lowest index to highest. |
| . The fence signal operation defined by the pname:fence parameter of a |
| flink:vkQueueSubmit, |
| ifdef::VK_KHR_synchronization2[] |
| flink:vkQueueSubmit2KHR, |
| endif::VK_KHR_synchronization2[] |
| or flink:vkQueueBindSparse command is ordered after all semaphore signal |
| operations defined by that command. |
| |
| Semaphore signal operations defined by a single slink:VkSubmitInfo, |
| ifdef::VK_KHR_synchronization2[] |
| slink:VkSubmitInfo2KHR, |
| endif::VK_KHR_synchronization2[] |
| or slink:VkBindSparseInfo structure are unordered with respect to other |
| semaphore signal operations defined within the same structure. |
| |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| The flink:vkSignalSemaphore command does not execute on a queue but instead |
| performs the signal operation from the host. |
| The semaphore signal operation defined by executing a |
| flink:vkSignalSemaphore command happens-after the flink:vkSignalSemaphore |
| command is invoked and happens-before the command returns. |
| |
| [NOTE] |
| .Note |
| ==== |
| When signaling timeline semaphores, it is the responsibility of the |
| application to ensure that they are ordered such that the semaphore value is |
| strictly increasing. |
| Because the first synchronization scope for a semaphore signal operation |
| contains all semaphore signal operations which occur earlier in submission |
| order, all semaphore signal operations contained in any given batch are |
| guaranteed to happen-after all semaphore signal operations contained in any |
| previous batches. |
| However, no ordering guarantee is provided between the semaphore signal |
| operations defined within a single batch. |
| This, combined with the requirement that timeline semaphore values strictly |
| increase, means that it is invalid to signal the same timeline semaphore |
| twice within a single batch. |
| |
| If an application wishes to ensure that some semaphore signal operation |
| happens-after some other semaphore signal operation, it can submit a |
| separate batch containing only semaphore signal operations, which will |
| happen-after the semaphore signal operations in any earlier batches. |
| |
| When signaling a semaphore from the host, the only ordering guarantee is |
| that the signal operation happens-after when flink:vkSignalSemaphore is |
| called and happens-before it returns. |
| Therefore, it is invalid to call fname:vkSignalSemaphore while there are any |
| outstanding signal operations on that semaphore from any queue submissions |
| unless those queue submissions have some dependency which ensures that they |
| happen-after the host signal operation. |
| One example of this would be if the pending signal operation is, itself, |
| waiting on the same semaphore at a lower value and the call to |
| fname:vkSignalSemaphore signals that lower value. |
| Furthermore, if there are two or more processes or threads signaling the |
| same timeline semaphore from the host, the application must ensure that the |
| fname:vkSignalSemaphore with the lower semaphore value returns before |
| fname:vkSignalSemaphore is called with the higher value. |
| ==== |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| |
| |
| [[synchronization-fences]] |
| == Fences |
| |
| [open,refpage='VkFence',desc='Opaque handle to a fence object',type='handles'] |
| -- |
| Fences are a synchronization primitive that can: be used to insert a |
| dependency from a queue to the host. |
| Fences have two states - signaled and unsignaled. |
| A fence can: be signaled as part of the execution of a |
| <<devsandqueues-submission, queue submission>> command. |
| Fences can: be unsignaled on the host with flink:vkResetFences. |
| Fences can: be waited on by the host with the flink:vkWaitForFences command, |
| and the current state can: be queried with flink:vkGetFenceStatus. |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_fence[] |
| [[synchronization-fences-payloads]] |
| The internal data of a fence may: include a reference to any resources and |
| pending work associated with signal or unsignal operations performed on that |
| fence object, collectively referred to as the fence's _payload_. |
| Mechanisms to import and export that internal data to and from fences are |
| provided <<VkExportFenceCreateInfo, below>>. |
| These mechanisms indirectly enable applications to share fence state between |
| two or more fences and other synchronization primitives across process and |
| API boundaries. |
| |
| endif::VK_VERSION_1_1,VK_KHR_external_fence[] |
| |
| Fences are represented by sname:VkFence handles: |
| |
| include::{generated}/api/handles/VkFence.txt[] |
| -- |
| |
| [open,refpage='vkCreateFence',desc='Create a new fence object',type='protos'] |
| -- |
| To create a fence, call: |
| |
| include::{generated}/api/protos/vkCreateFence.txt[] |
| |
| * pname:device is the logical device that creates the fence. |
| * pname:pCreateInfo is a pointer to a slink:VkFenceCreateInfo structure |
| containing information about how the fence is to be created. |
| * pname:pAllocator controls host memory allocation as described in the |
| <<memory-allocation, Memory Allocation>> chapter. |
| * pname:pFence is a pointer to a handle in which the resulting fence |
| object is returned. |
| |
| include::{generated}/validity/protos/vkCreateFence.txt[] |
| -- |
| |
| [open,refpage='VkFenceCreateInfo',desc='Structure specifying parameters of a newly created fence',type='structs'] |
| -- |
| The sname:VkFenceCreateInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkFenceCreateInfo.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:flags is a bitmask of elink:VkFenceCreateFlagBits specifying the |
| initial state and behavior of the fence. |
| |
| include::{generated}/validity/structs/VkFenceCreateInfo.txt[] |
| -- |
| |
| [open,refpage='VkFenceCreateFlagBits',desc='Bitmask specifying initial state and behavior of a fence',type='enums'] |
| -- |
| include::{generated}/api/enums/VkFenceCreateFlagBits.txt[] |
| |
| * ename:VK_FENCE_CREATE_SIGNALED_BIT specifies that the fence object is |
| created in the signaled state. |
| Otherwise, it is created in the unsignaled state. |
| -- |
| |
| [open,refpage='VkFenceCreateFlags',desc='Bitmask of VkFenceCreateFlagBits',type='flags'] |
| -- |
| include::{generated}/api/flags/VkFenceCreateFlags.txt[] |
| |
| tname:VkFenceCreateFlags is a bitmask type for setting a mask of zero or |
| more elink:VkFenceCreateFlagBits. |
| -- |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_fence[] |
| [open,refpage='VkExportFenceCreateInfo',desc='Structure specifying handle types that can be exported from a fence',type='structs'] |
| -- |
| To create a fence whose payload can: be exported to external handles, add a |
| slink:VkExportFenceCreateInfo structure to the pname:pNext chain of the |
| slink:VkFenceCreateInfo structure. |
| The sname:VkExportFenceCreateInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkExportFenceCreateInfo.txt[] |
| |
| ifdef::VK_KHR_external_fence[] |
| or the equivalent |
| |
| include::{generated}/api/structs/VkExportFenceCreateInfoKHR.txt[] |
| endif::VK_KHR_external_fence[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:handleTypes is a bitmask of |
| elink:VkExternalFenceHandleTypeFlagBits specifying one or more fence |
| handle types the application can: export from the resulting fence. |
| The application can: request multiple handle types for the same fence. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkExportFenceCreateInfo-handleTypes-01446]] |
| The bits in pname:handleTypes must: be supported and compatible, as |
| reported by slink:VkExternalFenceProperties |
| **** |
| |
| include::{generated}/validity/structs/VkExportFenceCreateInfo.txt[] |
| -- |
| endif::VK_VERSION_1_1,VK_KHR_external_fence[] |
| |
| ifdef::VK_KHR_external_fence_win32[] |
| [open,refpage='VkExportFenceWin32HandleInfoKHR',desc='Structure specifying additional attributes of Windows handles exported from a fence',type='structs'] |
| -- |
| To specify additional attributes of NT handles exported from a fence, add a |
| slink:VkExportFenceWin32HandleInfoKHR structure to the pname:pNext chain of |
| the slink:VkFenceCreateInfo structure. |
| The sname:VkExportFenceWin32HandleInfoKHR structure is defined as: |
| |
| include::{generated}/api/structs/VkExportFenceWin32HandleInfoKHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:pAttributes is a pointer to a Windows code:SECURITY_ATTRIBUTES |
| structure specifying security attributes of the handle. |
| * pname:dwAccess is a code:DWORD specifying access rights of the handle. |
| * pname:name is a null-terminated UTF-16 string to associate with the |
| underlying synchronization primitive referenced by NT handles exported |
| from the created fence. |
| |
| If slink:VkExportFenceCreateInfo is not inluded in the same pname:pNext |
| chain, this structure is ignored. |
| |
| If slink:VkExportFenceCreateInfo is included in the pname:pNext chain of |
| slink:VkFenceCreateInfo with a Windows pname:handleType, but either |
| sname:VkExportFenceWin32HandleInfoKHR is not included in the pname:pNext |
| chain, or if it is but pname:pAttributes is set to `NULL`, default security |
| descriptor values will be used, and child processes created by the |
| application will not inherit the handle, as described in the MSDN |
| documentation for "`Synchronization Object Security and Access Rights`"^1^. |
| Further, if the structure is not present, the access rights will be |
| |
| code:DXGI_SHARED_RESOURCE_READ | code:DXGI_SHARED_RESOURCE_WRITE |
| |
| for handles of the following types: |
| |
| ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT |
| |
| 1:: |
| https://docs.microsoft.com/en-us/windows/win32/sync/synchronization-object-security-and-access-rights |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkExportFenceWin32HandleInfoKHR-handleTypes-01447]] |
| If slink:VkExportFenceCreateInfo::pname:handleTypes does not include |
| ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT, a |
| sname:VkExportFenceWin32HandleInfoKHR structure must: not be included in |
| the pname:pNext chain of slink:VkFenceCreateInfo |
| **** |
| |
| include::{generated}/validity/structs/VkExportFenceWin32HandleInfoKHR.txt[] |
| -- |
| |
| [open,refpage='vkGetFenceWin32HandleKHR',desc='Get a Windows HANDLE for a fence',type='protos'] |
| -- |
| To export a Windows handle representing the state of a fence, call: |
| |
| include::{generated}/api/protos/vkGetFenceWin32HandleKHR.txt[] |
| |
| * pname:device is the logical device that created the fence being |
| exported. |
| * pname:pGetWin32HandleInfo is a pointer to a |
| slink:VkFenceGetWin32HandleInfoKHR structure containing parameters of |
| the export operation. |
| * pname:pHandle will return the Windows handle representing the fence |
| state. |
| |
| For handle types defined as NT handles, the handles returned by |
| fname:vkGetFenceWin32HandleKHR are owned by the application. |
| To avoid leaking resources, the application must: release ownership of them |
| using the code:CloseHandle system call when they are no longer needed. |
| |
| Exporting a Windows handle from a fence may: have side effects depending on |
| the transference of the specified handle type, as described in |
| <<synchronization-fences-importing,Importing Fence Payloads>>. |
| |
| include::{generated}/validity/protos/vkGetFenceWin32HandleKHR.txt[] |
| -- |
| |
| [open,refpage='VkFenceGetWin32HandleInfoKHR',desc='Structure describing a Win32 handle fence export operation',type='structs'] |
| -- |
| The sname:VkFenceGetWin32HandleInfoKHR structure is defined as: |
| |
| include::{generated}/api/structs/VkFenceGetWin32HandleInfoKHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:fence is the fence from which state will be exported. |
| * pname:handleType is a elink:VkExternalFenceHandleTypeFlagBits value |
| specifying the type of handle requested. |
| |
| The properties of the handle returned depend on the value of |
| pname:handleType. |
| See elink:VkExternalFenceHandleTypeFlagBits for a description of the |
| properties of the defined external fence handle types. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkFenceGetWin32HandleInfoKHR-handleType-01448]] |
| pname:handleType must: have been included in |
| slink:VkExportFenceCreateInfo::pname:handleTypes when the pname:fence's |
| current payload was created |
| * [[VUID-VkFenceGetWin32HandleInfoKHR-handleType-01449]] |
| If pname:handleType is defined as an NT handle, |
| flink:vkGetFenceWin32HandleKHR must: be called no more than once for |
| each valid unique combination of pname:fence and pname:handleType |
| * [[VUID-VkFenceGetWin32HandleInfoKHR-fence-01450]] |
| pname:fence must: not currently have its payload replaced by an imported |
| payload as described below in |
| <<synchronization-fences-importing,Importing Fence Payloads>> unless |
| that imported payload's handle type was included in |
| slink:VkExternalFenceProperties::pname:exportFromImportedHandleTypes for |
| pname:handleType |
| * [[VUID-VkFenceGetWin32HandleInfoKHR-handleType-01451]] |
| If pname:handleType refers to a handle type with copy payload |
| transference semantics, pname:fence must: be signaled, or have an |
| associated <<synchronization-fences-signaling,fence signal operation>> |
| pending execution |
| * [[VUID-VkFenceGetWin32HandleInfoKHR-handleType-01452]] |
| pname:handleType must: be defined as an NT handle or a global share |
| handle |
| **** |
| |
| include::{generated}/validity/structs/VkFenceGetWin32HandleInfoKHR.txt[] |
| -- |
| endif::VK_KHR_external_fence_win32[] |
| |
| ifdef::VK_KHR_external_fence_fd[] |
| [open,refpage='vkGetFenceFdKHR',desc='Get a POSIX file descriptor handle for a fence',type='protos'] |
| -- |
| To export a POSIX file descriptor representing the payload of a fence, call: |
| |
| include::{generated}/api/protos/vkGetFenceFdKHR.txt[] |
| |
| * pname:device is the logical device that created the fence being |
| exported. |
| * pname:pGetFdInfo is a pointer to a slink:VkFenceGetFdInfoKHR structure |
| containing parameters of the export operation. |
| * pname:pFd will return the file descriptor representing the fence |
| payload. |
| |
| Each call to fname:vkGetFenceFdKHR must: create a new file descriptor and |
| transfer ownership of it to the application. |
| To avoid leaking resources, the application must: release ownership of the |
| file descriptor when it is no longer needed. |
| |
| [NOTE] |
| .Note |
| ==== |
| Ownership can be released in many ways. |
| For example, the application can call code:close() on the file descriptor, |
| or transfer ownership back to Vulkan by using the file descriptor to import |
| a fence payload. |
| ==== |
| |
| If pname:pGetFdInfo->handleType is |
| ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT and the fence is signaled at |
| the time fname:vkGetFenceFdKHR is called, pname:pFd may: return the value |
| `-1` instead of a valid file descriptor. |
| |
| Where supported by the operating system, the implementation must: set the |
| file descriptor to be closed automatically when an code:execve system call |
| is made. |
| |
| Exporting a file descriptor from a fence may: have side effects depending on |
| the transference of the specified handle type, as described in |
| <<synchronization-fences-importing,Importing Fence State>>. |
| |
| include::{generated}/validity/protos/vkGetFenceFdKHR.txt[] |
| -- |
| |
| [open,refpage='VkFenceGetFdInfoKHR',desc='Structure describing a POSIX FD fence export operation',type='structs'] |
| -- |
| The sname:VkFenceGetFdInfoKHR structure is defined as: |
| |
| include::{generated}/api/structs/VkFenceGetFdInfoKHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:fence is the fence from which state will be exported. |
| * pname:handleType is a elink:VkExternalFenceHandleTypeFlagBits value |
| specifying the type of handle requested. |
| |
| The properties of the file descriptor returned depend on the value of |
| pname:handleType. |
| See elink:VkExternalFenceHandleTypeFlagBits for a description of the |
| properties of the defined external fence handle types. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkFenceGetFdInfoKHR-handleType-01453]] |
| pname:handleType must: have been included in |
| slink:VkExportFenceCreateInfo::pname:handleTypes when pname:fence's |
| current payload was created |
| * [[VUID-VkFenceGetFdInfoKHR-handleType-01454]] |
| If pname:handleType refers to a handle type with copy payload |
| transference semantics, pname:fence must: be signaled, or have an |
| associated <<synchronization-fences-signaling,fence signal operation>> |
| pending execution |
| * [[VUID-VkFenceGetFdInfoKHR-fence-01455]] |
| pname:fence must: not currently have its payload replaced by an imported |
| payload as described below in |
| <<synchronization-fences-importing,Importing Fence Payloads>> unless |
| that imported payload's handle type was included in |
| slink:VkExternalFenceProperties::pname:exportFromImportedHandleTypes for |
| pname:handleType |
| * [[VUID-VkFenceGetFdInfoKHR-handleType-01456]] |
| pname:handleType must: be defined as a POSIX file descriptor handle |
| **** |
| |
| include::{generated}/validity/structs/VkFenceGetFdInfoKHR.txt[] |
| -- |
| endif::VK_KHR_external_fence_fd[] |
| |
| [open,refpage='vkDestroyFence',desc='Destroy a fence object',type='protos'] |
| -- |
| To destroy a fence, call: |
| |
| include::{generated}/api/protos/vkDestroyFence.txt[] |
| |
| * pname:device is the logical device that destroys the fence. |
| * pname:fence is the handle of the fence to destroy. |
| * pname:pAllocator controls host memory allocation as described in the |
| <<memory-allocation, Memory Allocation>> chapter. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkDestroyFence-fence-01120]] |
| All <<devsandqueues-submission, queue submission>> commands that refer |
| to pname:fence must: have completed execution |
| * [[VUID-vkDestroyFence-fence-01121]] |
| If sname:VkAllocationCallbacks were provided when pname:fence was |
| created, a compatible set of callbacks must: be provided here |
| * [[VUID-vkDestroyFence-fence-01122]] |
| If no sname:VkAllocationCallbacks were provided when pname:fence was |
| created, pname:pAllocator must: be `NULL` |
| **** |
| |
| include::{generated}/validity/protos/vkDestroyFence.txt[] |
| -- |
| |
| [open,refpage='vkGetFenceStatus',desc='Return the status of a fence',type='protos'] |
| -- |
| To query the status of a fence from the host, call: |
| |
| include::{generated}/api/protos/vkGetFenceStatus.txt[] |
| |
| * pname:device is the logical device that owns the fence. |
| * pname:fence is the handle of the fence to query. |
| |
| Upon success, fname:vkGetFenceStatus returns the status of the fence object, |
| with the following return codes: |
| |
| .Fence Object Status Codes |
| [width="80%",options="header"] |
| |==== |
| | Status | Meaning |
| | ename:VK_SUCCESS | The fence specified by pname:fence is signaled. |
| | ename:VK_NOT_READY | The fence specified by pname:fence is unsignaled. |
| | ename:VK_ERROR_DEVICE_LOST | The device has been lost. See <<devsandqueues-lost-device,Lost Device>>. |
| |==== |
| |
| If a <<devsandqueues-submission, queue submission>> command is pending |
| execution, then the value returned by this command may: immediately be out |
| of date. |
| |
| If the device has been lost (see <<devsandqueues-lost-device,Lost Device>>), |
| fname:vkGetFenceStatus may: return any of the above status codes. |
| If the device has been lost and fname:vkGetFenceStatus is called repeatedly, |
| it will eventually return either ename:VK_SUCCESS or |
| ename:VK_ERROR_DEVICE_LOST. |
| |
| include::{generated}/validity/protos/vkGetFenceStatus.txt[] |
| -- |
| |
| [[synchronization-fences-unsignaling]] |
| [open,refpage='vkResetFences',desc='Resets one or more fence objects',type='protos'] |
| -- |
| To set the state of fences to unsignaled from the host, call: |
| |
| include::{generated}/api/protos/vkResetFences.txt[] |
| |
| * pname:device is the logical device that owns the fences. |
| * pname:fenceCount is the number of fences to reset. |
| * pname:pFences is a pointer to an array of fence handles to reset. |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_fence[] |
| |
| If any member of pname:pFences currently has its |
| <<synchronization-fences-importing, payload imported>> with temporary |
| permanence, that fence's prior permanent payload is first restored. |
| The remaining operations described therefore operate on the restored |
| payload. |
| |
| endif::VK_VERSION_1_1,VK_KHR_external_fence[] |
| |
| When flink:vkResetFences is executed on the host, it defines a _fence |
| unsignal operation_ for each fence, which resets the fence to the unsignaled |
| state. |
| |
| If any member of pname:pFences is already in the unsignaled state when |
| flink:vkResetFences is executed, then flink:vkResetFences has no effect on |
| that fence. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkResetFences-pFences-01123]] |
| Each element of pname:pFences must: not be currently associated with any |
| queue command that has not yet completed execution on that queue |
| **** |
| |
| include::{generated}/validity/protos/vkResetFences.txt[] |
| -- |
| |
| [[synchronization-fences-signaling]] |
| When a fence is submitted to a queue as part of a |
| <<devsandqueues-submission, queue submission>> command, it defines a memory |
| dependency on the batches that were submitted as part of that command, and |
| defines a _fence signal operation_ which sets the fence to the signaled |
| state. |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> |
| includes every batch submitted in the same <<devsandqueues-submission, queue |
| submission>> command. |
| Fence signal operations that are defined by flink:vkQueueSubmit additionally |
| include in the first synchronization scope all commands that occur earlier |
| in <<synchronization-submission-order,submission order>>. |
| Fence signal operations that are defined by flink:vkQueueSubmit or |
| flink:vkQueueBindSparse additionally include in the first synchronization |
| scope any semaphore and fence signal operations that occur earlier in |
| <<synchronization-signal-operation-order,signal operation order>>. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| only includes the fence signal operation. |
| |
| The first <<synchronization-dependencies-access-scopes, access scope>> |
| includes all memory access performed by the device. |
| |
| The second <<synchronization-dependencies-access-scopes, access scope>> is |
| empty. |
| |
| [open,refpage='vkWaitForFences',desc='Wait for one or more fences to become signaled',type='protos'] |
| -- |
| To wait for one or more fences to enter the signaled state on the host, |
| call: |
| |
| include::{generated}/api/protos/vkWaitForFences.txt[] |
| |
| * pname:device is the logical device that owns the fences. |
| * pname:fenceCount is the number of fences to wait on. |
| * pname:pFences is a pointer to an array of pname:fenceCount fence |
| handles. |
| * pname:waitAll is the condition that must: be satisfied to successfully |
| unblock the wait. |
| If pname:waitAll is ename:VK_TRUE, then the condition is that all fences |
| in pname:pFences are signaled. |
| Otherwise, the condition is that at least one fence in pname:pFences is |
| signaled. |
| * pname:timeout is the timeout period in units of nanoseconds. |
| pname:timeout is adjusted to the closest value allowed by the |
| implementation-dependent timeout accuracy, which may: be substantially |
| longer than one nanosecond, and may: be longer than the requested |
| period. |
| |
| If the condition is satisfied when fname:vkWaitForFences is called, then |
| fname:vkWaitForFences returns immediately. |
| If the condition is not satisfied at the time fname:vkWaitForFences is |
| called, then fname:vkWaitForFences will block and wait until the condition |
| is satisfied or the pname:timeout has expired, whichever is sooner. |
| |
| If pname:timeout is zero, then fname:vkWaitForFences does not wait, but |
| simply returns the current state of the fences. |
| ename:VK_TIMEOUT will be returned in this case if the condition is not |
| satisfied, even though no actual wait was performed. |
| |
| If the condition is satisfied before the pname:timeout has expired, |
| fname:vkWaitForFences returns ename:VK_SUCCESS. |
| Otherwise, fname:vkWaitForFences returns ename:VK_TIMEOUT after the |
| pname:timeout has expired. |
| |
| If device loss occurs (see <<devsandqueues-lost-device,Lost Device>>) before |
| the timeout has expired, fname:vkWaitForFences must: return in finite time |
| with either ename:VK_SUCCESS or ename:VK_ERROR_DEVICE_LOST. |
| |
| [NOTE] |
| .Note |
| ==== |
| While we guarantee that fname:vkWaitForFences must: return in finite time, |
| no guarantees are made that it returns immediately upon device loss. |
| However, the client can reasonably expect that the delay will be on the |
| order of seconds and that calling fname:vkWaitForFences will not result in a |
| permanently (or seemingly permanently) dead process. |
| ==== |
| |
| include::{generated}/validity/protos/vkWaitForFences.txt[] |
| -- |
| |
| [[synchronization-fences-waiting]] |
| An execution dependency is defined by waiting for a fence to become |
| signaled, either via flink:vkWaitForFences or by polling on |
| flink:vkGetFenceStatus. |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> |
| includes only the fence signal operation. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| includes the host operations of flink:vkWaitForFences or |
| flink:vkGetFenceStatus indicating that the fence has become signaled. |
| |
| [NOTE] |
| .Note |
| ==== |
| Signaling a fence and waiting on the host does not guarantee that the |
| results of memory accesses will be visible to the host, as the access scope |
| of a memory dependency defined by a fence only includes device access. |
| A <<synchronization-memory-barriers, memory barrier>> or other memory |
| dependency must: be used to guarantee this. |
| See the description of <<synchronization-host-access-types, host access |
| types>> for more information. |
| ==== |
| |
| ifdef::VK_EXT_display_control[] |
| include::VK_EXT_display_control/fence_events.txt[] |
| endif::VK_EXT_display_control[] |
| |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_fence[] |
| [[synchronization-fences-importing]] |
| === Importing Fence Payloads |
| |
| Applications can: import a fence payload into an existing fence using an |
| external fence handle. |
| The effects of the import operation will be either temporary or permanent, |
| as specified by the application. |
| If the import is temporary, the fence will be _restored_ to its permanent |
| state the next time that fence is passed to flink:vkResetFences. |
| |
| [NOTE] |
| .Note |
| ==== |
| Restoring a fence to its prior permanent payload is a distinct operation |
| from resetting a fence payload. |
| See flink:vkResetFences for more detail. |
| ==== |
| |
| Performing a subsequent temporary import on a fence before resetting it has |
| no effect on this requirement; the next unsignal of the fence must: still |
| restore its last permanent state. |
| A permanent payload import behaves as if the target fence was destroyed, and |
| a new fence was created with the same handle but the imported payload. |
| Because importing a fence payload temporarily or permanently detaches the |
| existing payload from a fence, similar usage restrictions to those applied |
| to fname:vkDestroyFence are applied to any command that imports a fence |
| payload. |
| Which of these import types is used is referred to as the import operation's |
| _permanence_. |
| Each handle type supports either one or both types of permanence. |
| |
| The implementation must: perform the import operation by either referencing |
| or copying the payload referred to by the specified external fence handle, |
| depending on the handle's type. |
| The import method used is referred to as the handle type's _transference_. |
| When using handle types with reference transference, importing a payload to |
| a fence adds the fence to the set of all fences sharing that payload. |
| This set includes the fence from which the payload was exported. |
| Fence signaling, waiting, and resetting operations performed on any fence in |
| the set must: behave as if the set were a single fence. |
| Importing a payload using handle types with copy transference creates a |
| duplicate copy of the payload at the time of import, but makes no further |
| reference to it. |
| Fence signaling, waiting, and resetting operations performed on the target |
| of copy imports must: not affect any other fence or payload. |
| |
| Export operations have the same transference as the specified handle type's |
| import operations. |
| Additionally, exporting a fence payload to a handle with copy transference |
| has the same side effects on the source fence's payload as executing a fence |
| reset operation. |
| If the fence was using a temporarily imported payload, the fence's prior |
| permanent payload will be restored. |
| |
| ifdef::VK_KHR_external_fence_win32,VK_KHR_external_fence_fd[] |
| [NOTE] |
| .Note |
| ==== |
| The |
| ifdef::VK_KHR_external_fence_win32+VK_KHR_external_fence_fd[tables] |
| ifndef::VK_KHR_external_fence_win32+VK_KHR_external_fence_fd[table] |
| ifdef::VK_KHR_external_fence_win32[] |
| <<synchronization-fence-handletypes-win32,Handle Types Supported by |
| sname:VkImportFenceWin32HandleInfoKHR>> |
| endif::VK_KHR_external_fence_win32[] |
| ifdef::VK_KHR_external_fence_win32+VK_KHR_external_fence_fd[and] |
| ifdef::VK_KHR_external_fence_fd[] |
| <<synchronization-fence-handletypes-fd,Handle Types Supported by |
| sname:VkImportFenceFdInfoKHR>> |
| endif::VK_KHR_external_fence_fd[] |
| ifdef::VK_KHR_external_fence_win32+VK_KHR_external_fence_fd[define] |
| ifndef::VK_KHR_external_fence_win32+VK_KHR_external_fence_fd[defines] |
| the permanence and transference of each handle type. |
| ==== |
| endif::VK_KHR_external_fence_win32,VK_KHR_external_fence_fd[] |
| |
| <<fundamentals-threadingbehavior,External synchronization>> allows |
| implementations to modify an object's internal state, i.e. payload, without |
| internal synchronization. |
| However, for fences sharing a payload across processes, satisfying the |
| external synchronization requirements of sname:VkFence parameters as if all |
| fences in the set were the same object is sometimes infeasible. |
| Satisfying valid usage constraints on the state of a fence would similarly |
| require impractical coordination or levels of trust between processes. |
| Therefore, these constraints only apply to a specific fence handle, not to |
| its payload. |
| For distinct fence objects which share a payload: |
| |
| * If multiple commands which queue a signal operation, or which unsignal a |
| fence, are called concurrently, behavior will be as if the commands were |
| called in an arbitrary sequential order. |
| * If a queue submission command is called with a fence that is sharing a |
| payload, and the payload is already associated with another queue |
| command that has not yet completed execution, either one or both of the |
| commands will cause the fence to become signaled when they complete |
| execution. |
| * If a fence payload is reset while it is associated with a queue command |
| that has not yet completed execution, the payload will become |
| unsignaled, but may: become signaled again when the command completes |
| execution. |
| * In the preceding cases, any of the devices associated with the fences |
| sharing the payload may: be lost, or any of the queue submission or |
| fence reset commands may: return ename:VK_ERROR_INITIALIZATION_FAILED. |
| |
| Other than these non-deterministic results, behavior is well defined. |
| In particular: |
| |
| * The implementation must: not crash or enter an internally inconsistent |
| state where future valid Vulkan commands might cause undefined: results, |
| * Timeouts on future wait commands on fences sharing the payload must: be |
| effective. |
| |
| [NOTE] |
| .Note |
| ==== |
| These rules allow processes to synchronize access to shared memory without |
| trusting each other. |
| However, such processes must still be cautious not to use the shared fence |
| for more than synchronizing access to the shared memory. |
| For example, a process should not use a fence with shared payload to tell |
| when commands it submitted to a queue have completed and objects used by |
| those commands may be destroyed, since the other process can accidentally or |
| maliciously cause the fence to signal before the commands actually complete. |
| ==== |
| |
| When a fence is using an imported payload, its |
| slink:VkExportFenceCreateInfo::pname:handleTypes value is that specified |
| when creating the fence from which the payload was exported, rather than |
| that specified when creating the fence. |
| Additionally, |
| slink:VkExternalFenceProperties::pname:exportFromImportedHandleTypes |
| restricts which handle types can: be exported from such a fence based on the |
| specific handle type used to import the current payload. |
| ifdef::VK_KHR_swapchain[] |
| Passing a fence to flink:vkAcquireNextImageKHR is equivalent to temporarily |
| importing a fence payload to that fence. |
| |
| [NOTE] |
| .Note |
| ==== |
| Because the exportable handle types of an imported fence correspond to its |
| current imported payload, and flink:vkAcquireNextImageKHR behaves the same |
| as a temporary import operation for which the source fence is opaque to the |
| application, applications have no way of determining whether any external |
| handle types can: be exported from a fence in this state. |
| Therefore, applications must: not attempt to export handles from fences |
| using a temporarily imported payload from flink:vkAcquireNextImageKHR. |
| ==== |
| endif::VK_KHR_swapchain[] |
| |
| When importing a fence payload, it is the responsibility of the application |
| to ensure the external handles meet all valid usage requirements. |
| However, implementations must: perform sufficient validation of external |
| handles to ensure that the operation results in a valid fence which will not |
| cause program termination, device loss, queue stalls, host thread stalls, or |
| corruption of other resources when used as allowed according to its import |
| parameters. |
| If the external handle provided does not meet these requirements, the |
| implementation must: fail the fence payload import operation with the error |
| code ename:VK_ERROR_INVALID_EXTERNAL_HANDLE. |
| endif::VK_VERSION_1_1,VK_KHR_external_fence[] |
| |
| ifdef::VK_KHR_external_fence_win32[] |
| [open,refpage='vkImportFenceWin32HandleKHR',desc='Import a fence from a Windows HANDLE',type='protos'] |
| -- |
| To import a fence payload from a Windows handle, call: |
| |
| include::{generated}/api/protos/vkImportFenceWin32HandleKHR.txt[] |
| |
| * pname:device is the logical device that created the fence. |
| * pname:pImportFenceWin32HandleInfo is a pointer to a |
| slink:VkImportFenceWin32HandleInfoKHR structure specifying the fence and |
| import parameters. |
| |
| Importing a fence payload from Windows handles does not transfer ownership |
| of the handle to the Vulkan implementation. |
| For handle types defined as NT handles, the application must: release |
| ownership using the code:CloseHandle system call when the handle is no |
| longer needed. |
| |
| Applications can: import the same fence payload into multiple instances of |
| Vulkan, into the same instance from which it was exported, and multiple |
| times into a given Vulkan instance. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkImportFenceWin32HandleKHR-fence-04448]] |
| pname:fence must: not be associated with any queue command that has not |
| yet completed execution on that queue |
| **** |
| |
| include::{generated}/validity/protos/vkImportFenceWin32HandleKHR.txt[] |
| -- |
| |
| [open,refpage='VkImportFenceWin32HandleInfoKHR',desc='(None)',type='structs'] |
| -- |
| The sname:VkImportFenceWin32HandleInfoKHR structure is defined as: |
| |
| include::{generated}/api/structs/VkImportFenceWin32HandleInfoKHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:fence is the fence into which the state will be imported. |
| * pname:flags is a bitmask of elink:VkFenceImportFlagBits specifying |
| additional parameters for the fence payload import operation. |
| * pname:handleType is a elink:VkExternalFenceHandleTypeFlagBits value |
| specifying the type of pname:handle. |
| * pname:handle is `NULL` or the external handle to import. |
| * pname:name is `NULL` or a null-terminated UTF-16 string naming the |
| underlying synchronization primitive to import. |
| |
| The handle types supported by pname:handleType are: |
| |
| [[synchronization-fence-handletypes-win32]] |
| .Handle Types Supported by sname:VkImportFenceWin32HandleInfoKHR |
| [width="80%",options="header"] |
| |==== |
| | Handle Type | Transference | Permanence Supported |
| | ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT | Reference | Temporary,Permanent |
| | ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT | Reference | Temporary,Permanent |
| |==== |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkImportFenceWin32HandleInfoKHR-handleType-01457]] |
| pname:handleType must: be a value included in the |
| <<synchronization-fence-handletypes-win32, Handle Types Supported by |
| sname:VkImportFenceWin32HandleInfoKHR>> table |
| * [[VUID-VkImportFenceWin32HandleInfoKHR-handleType-01459]] |
| If pname:handleType is not |
| ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT, pname:name must: |
| be `NULL` |
| * [[VUID-VkImportFenceWin32HandleInfoKHR-handleType-01460]] |
| If pname:handle is `NULL`, pname:name must: name a valid synchronization |
| primitive of the type specified by pname:handleType |
| * [[VUID-VkImportFenceWin32HandleInfoKHR-handleType-01461]] |
| If pname:name is `NULL`, pname:handle must: be a valid handle of the |
| type specified by pname:handleType |
| * [[VUID-VkImportFenceWin32HandleInfoKHR-handle-01462]] |
| If pname:handle is not `NULL`, pname:name must: be `NULL` |
| * [[VUID-VkImportFenceWin32HandleInfoKHR-handle-01539]] |
| If pname:handle is not `NULL`, it must: obey any requirements listed for |
| pname:handleType in <<external-fence-handle-types-compatibility,external |
| fence handle types compatibility>> |
| * [[VUID-VkImportFenceWin32HandleInfoKHR-name-01540]] |
| If pname:name is not `NULL`, it must: obey any requirements listed for |
| pname:handleType in <<external-fence-handle-types-compatibility,external |
| fence handle types compatibility>> |
| **** |
| |
| include::{generated}/validity/structs/VkImportFenceWin32HandleInfoKHR.txt[] |
| -- |
| endif::VK_KHR_external_fence_win32[] |
| |
| ifdef::VK_KHR_external_fence_fd[] |
| [open,refpage='vkImportFenceFdKHR',desc='Import a fence from a POSIX file descriptor',type='protos'] |
| -- |
| To import a fence payload from a POSIX file descriptor, call: |
| |
| include::{generated}/api/protos/vkImportFenceFdKHR.txt[] |
| |
| * pname:device is the logical device that created the fence. |
| * pname:pImportFenceFdInfo is a pointer to a slink:VkImportFenceFdInfoKHR |
| structure specifying the fence and import parameters. |
| |
| Importing a fence payload from a file descriptor transfers ownership of the |
| file descriptor from the application to the Vulkan implementation. |
| The application must: not perform any operations on the file descriptor |
| after a successful import. |
| |
| Applications can: import the same fence payload into multiple instances of |
| Vulkan, into the same instance from which it was exported, and multiple |
| times into a given Vulkan instance. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkImportFenceFdKHR-fence-01463]] |
| pname:fence must: not be associated with any queue command that has not |
| yet completed execution on that queue |
| **** |
| |
| include::{generated}/validity/protos/vkImportFenceFdKHR.txt[] |
| -- |
| |
| [open,refpage='VkImportFenceFdInfoKHR',desc='(None)',type='structs'] |
| -- |
| The sname:VkImportFenceFdInfoKHR structure is defined as: |
| |
| include::{generated}/api/structs/VkImportFenceFdInfoKHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:fence is the fence into which the payload will be imported. |
| * pname:flags is a bitmask of elink:VkFenceImportFlagBits specifying |
| additional parameters for the fence payload import operation. |
| * pname:handleType is a elink:VkExternalFenceHandleTypeFlagBits value |
| specifying the type of pname:fd. |
| * pname:fd is the external handle to import. |
| |
| The handle types supported by pname:handleType are: |
| |
| [[synchronization-fence-handletypes-fd]] |
| .Handle Types Supported by sname:VkImportFenceFdInfoKHR |
| [width="80%",options="header"] |
| |==== |
| | Handle Type | Transference | Permanence Supported |
| | ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT | Reference | Temporary,Permanent |
| | ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT | Copy | Temporary |
| |==== |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkImportFenceFdInfoKHR-handleType-01464]] |
| pname:handleType must: be a value included in the |
| <<synchronization-fence-handletypes-fd, Handle Types Supported by |
| sname:VkImportFenceFdInfoKHR>> table |
| * [[VUID-VkImportFenceFdInfoKHR-fd-01541]] |
| pname:fd must: obey any requirements listed for pname:handleType in |
| <<external-fence-handle-types-compatibility,external fence handle types |
| compatibility>> |
| **** |
| |
| If pname:handleType is ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT, the |
| special value `-1` for pname:fd is treated like a valid sync file descriptor |
| referring to an object that has already signaled. |
| The import operation will succeed and the sname:VkFence will have a |
| temporarily imported payload as if a valid file descriptor had been |
| provided. |
| |
| [NOTE] |
| .Note |
| ==== |
| This special behavior for importing an invalid sync file descriptor allows |
| easier interoperability with other system APIs which use the convention that |
| an invalid sync file descriptor represents work that has already completed |
| and does not need to be waited for. |
| It is consistent with the option for implementations to return a `-1` file |
| descriptor when exporting a ename:VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT |
| from a sname:VkFence which is signaled. |
| ==== |
| |
| include::{generated}/validity/structs/VkImportFenceFdInfoKHR.txt[] |
| -- |
| endif::VK_KHR_external_fence_fd[] |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_fence[] |
| ifdef::VK_KHR_external_fence_win32,VK_KHR_external_fence_fd[] |
| [open,refpage='VkFenceImportFlagBits',desc='Bitmask specifying additional parameters of fence payload import',type='enums'] |
| -- |
| Bits which can: be set in |
| |
| ifdef::VK_KHR_external_fence_win32[] |
| * slink:VkImportFenceWin32HandleInfoKHR::pname:flags |
| endif::VK_KHR_external_fence_win32[] |
| ifdef::VK_KHR_external_fence_fd[] |
| * slink:VkImportFenceFdInfoKHR::pname:flags |
| endif::VK_KHR_external_fence_fd[] |
| |
| specifying additional parameters of a fence import operation are: |
| |
| include::{generated}/api/enums/VkFenceImportFlagBits.txt[] |
| |
| ifdef::VK_KHR_external_fence[] |
| or the equivalent |
| |
| include::{generated}/api/enums/VkFenceImportFlagBitsKHR.txt[] |
| endif::VK_KHR_external_fence[] |
| |
| * ename:VK_FENCE_IMPORT_TEMPORARY_BIT specifies that the fence payload |
| will be imported only temporarily, as described in |
| <<synchronization-fences-importing,Importing Fence Payloads>>, |
| regardless of the permanence of pname:handleType. |
| -- |
| |
| [open,refpage='VkFenceImportFlags',desc='Bitmask of VkFenceImportFlagBits',type='flags'] |
| -- |
| include::{generated}/api/flags/VkFenceImportFlags.txt[] |
| |
| ifdef::VK_KHR_external_fence[] |
| or the equivalent |
| |
| include::{generated}/api/flags/VkFenceImportFlagsKHR.txt[] |
| endif::VK_KHR_external_fence[] |
| |
| tname:VkFenceImportFlags is a bitmask type for setting a mask of zero or |
| more elink:VkFenceImportFlagBits. |
| -- |
| endif::VK_KHR_external_fence_win32,VK_KHR_external_fence_fd[] |
| endif::VK_VERSION_1_1,VK_KHR_external_fence[] |
| |
| |
| [[synchronization-semaphores]] |
| == Semaphores |
| |
| [open,refpage='VkSemaphore',desc='Opaque handle to a semaphore object',type='handles'] |
| -- |
| Semaphores are a synchronization primitive that can: be used to insert a |
| dependency |
| ifndef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| between queue operations. |
| Semaphores have two states - signaled and unsignaled. |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| between queue operations or between a queue operation and the host. |
| <<glossary, Binary semaphores>> have two states - signaled and unsignaled. |
| <<glossary, Timeline semaphores>> have a strictly increasing 64-bit unsigned |
| integer payload and are signaled with respect to a particular reference |
| value. |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| A semaphore can: be signaled after execution of a queue operation is |
| completed, and a queue operation can: wait for a semaphore to become |
| signaled before it begins execution. |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| A timeline semaphore can: additionally be signaled from the host with the |
| flink:vkSignalSemaphore command and waited on from the host with the |
| flink:vkWaitSemaphores command. |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_semaphore[] |
| [[synchronization-semaphores-payloads]] |
| The internal data of a semaphore may: include a reference to any resources |
| and pending work associated with signal or unsignal operations performed on |
| that semaphore object, collectively referred to as the semaphore's |
| _payload_. |
| Mechanisms to import and export that internal data to and from semaphores |
| are provided <<VkExportSemaphoreCreateInfo, below>>. |
| These mechanisms indirectly enable applications to share semaphore state |
| between two or more semaphores and other synchronization primitives across |
| process and API boundaries. |
| |
| endif::VK_VERSION_1_1,VK_KHR_external_semaphore[] |
| |
| Semaphores are represented by sname:VkSemaphore handles: |
| |
| include::{generated}/api/handles/VkSemaphore.txt[] |
| -- |
| |
| [open,refpage='vkCreateSemaphore',desc='Create a new queue semaphore object',type='protos'] |
| -- |
| To create a semaphore, call: |
| |
| include::{generated}/api/protos/vkCreateSemaphore.txt[] |
| |
| * pname:device is the logical device that creates the semaphore. |
| * pname:pCreateInfo is a pointer to a slink:VkSemaphoreCreateInfo |
| structure containing information about how the semaphore is to be |
| created. |
| * pname:pAllocator controls host memory allocation as described in the |
| <<memory-allocation, Memory Allocation>> chapter. |
| * pname:pSemaphore is a pointer to a handle in which the resulting |
| semaphore object is returned. |
| |
| ifndef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| This command creates a _binary semaphore_ that has a boolean payload |
| indicating whether the semaphore is currently signaled or unsignaled. |
| When created, the semaphore is in the unsignaled state. |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| |
| include::{generated}/validity/protos/vkCreateSemaphore.txt[] |
| -- |
| |
| [open,refpage='VkSemaphoreCreateInfo',desc='Structure specifying parameters of a newly created semaphore',type='structs'] |
| -- |
| The sname:VkSemaphoreCreateInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkSemaphoreCreateInfo.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:flags is reserved for future use. |
| |
| include::{generated}/validity/structs/VkSemaphoreCreateInfo.txt[] |
| -- |
| |
| [open,refpage='VkSemaphoreCreateFlags',desc='Reserved for future use',type='flags'] |
| -- |
| include::{generated}/api/flags/VkSemaphoreCreateFlags.txt[] |
| |
| tname:VkSemaphoreCreateFlags is a bitmask type for setting a mask, but is |
| currently reserved for future use. |
| -- |
| |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| [open,refpage='VkSemaphoreTypeCreateInfo',desc='Structure specifying the type of a newly created semaphore',type='structs',alias='VkSemaphoreTypeCreateInfoKHR'] |
| -- |
| The sname:VkSemaphoreTypeCreateInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkSemaphoreTypeCreateInfo.txt[] |
| |
| ifdef::VK_KHR_timeline_semaphore[] |
| or the equivalent |
| |
| include::{generated}/api/structs/VkSemaphoreTypeCreateInfoKHR.txt[] |
| endif::VK_KHR_timeline_semaphore[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:semaphoreType is a elink:VkSemaphoreType value specifying the type |
| of the semaphore. |
| * pname:initialValue is the initial payload value if pname:semaphoreType |
| is ename:VK_SEMAPHORE_TYPE_TIMELINE. |
| |
| To create a semaphore of a specific type, add a |
| sname:VkSemaphoreTypeCreateInfo structure to the |
| slink:VkSemaphoreCreateInfo::pname:pNext chain. |
| |
| If no sname:VkSemaphoreTypeCreateInfo structure is included in the |
| pname:pNext chain of slink:VkSemaphoreCreateInfo, then the created semaphore |
| will have a default elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_BINARY. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkSemaphoreTypeCreateInfo-timelineSemaphore-03252]] |
| If the <<features-timelineSemaphore,pname:timelineSemaphore>> feature is |
| not enabled, pname:semaphoreType must: not equal |
| ename:VK_SEMAPHORE_TYPE_TIMELINE |
| * [[VUID-VkSemaphoreTypeCreateInfo-semaphoreType-03279]] |
| If pname:semaphoreType is ename:VK_SEMAPHORE_TYPE_BINARY, |
| pname:initialValue must: be zero |
| **** |
| |
| include::{generated}/validity/structs/VkSemaphoreTypeCreateInfo.txt[] |
| -- |
| |
| [open,refpage='VkSemaphoreType',desc='Sepcifies the type of a semaphore object',type='enums',alias='VkSemaphoreTypeKHR'] |
| -- |
| Possible values of slink:VkSemaphoreTypeCreateInfo::pname:semaphoreType, |
| specifying the type of a semaphore, are: |
| |
| include::{generated}/api/enums/VkSemaphoreType.txt[] |
| |
| ifdef::VK_KHR_timeline_semaphore[] |
| or the equivalent |
| |
| include::{generated}/api/enums/VkSemaphoreTypeKHR.txt[] |
| endif::VK_KHR_timeline_semaphore[] |
| |
| * ename:VK_SEMAPHORE_TYPE_BINARY specifies a _binary semaphore_ type that |
| has a boolean payload indicating whether the semaphore is currently |
| signaled or unsignaled. |
| When created, the semaphore is in the unsignaled state. |
| * ename:VK_SEMAPHORE_TYPE_TIMELINE specifies a _timeline semaphore_ type |
| that has a strictly increasing 64-bit unsigned integer payload |
| indicating whether the semaphore is signaled with respect to a |
| particular reference value. |
| When created, the semaphore payload has the value given by the |
| pname:initialValue field of slink:VkSemaphoreTypeCreateInfo. |
| -- |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_semaphore[] |
| [open,refpage='VkExportSemaphoreCreateInfo',desc='Structure specifying handle types that can be exported from a semaphore',type='structs'] |
| -- |
| To create a semaphore whose payload can: be exported to external handles, |
| add a slink:VkExportSemaphoreCreateInfo structure to the pname:pNext chain |
| of the slink:VkSemaphoreCreateInfo structure. |
| The sname:VkExportSemaphoreCreateInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkExportSemaphoreCreateInfo.txt[] |
| |
| ifdef::VK_KHR_external_semaphore[] |
| or the equivalent |
| |
| include::{generated}/api/structs/VkExportSemaphoreCreateInfoKHR.txt[] |
| endif::VK_KHR_external_semaphore[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:handleTypes is a bitmask of |
| elink:VkExternalSemaphoreHandleTypeFlagBits specifying one or more |
| semaphore handle types the application can: export from the resulting |
| semaphore. |
| The application can: request multiple handle types for the same |
| semaphore. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkExportSemaphoreCreateInfo-handleTypes-01124]] |
| The bits in pname:handleTypes must: be supported and compatible, as |
| reported by slink:VkExternalSemaphoreProperties |
| **** |
| |
| include::{generated}/validity/structs/VkExportSemaphoreCreateInfo.txt[] |
| -- |
| endif::VK_VERSION_1_1,VK_KHR_external_semaphore[] |
| |
| ifdef::VK_KHR_external_semaphore_win32[] |
| [open,refpage='VkExportSemaphoreWin32HandleInfoKHR',desc='Structure specifying additional attributes of Windows handles exported from a semaphore',type='structs'] |
| -- |
| To specify additional attributes of NT handles exported from a semaphore, |
| add a sname:VkExportSemaphoreWin32HandleInfoKHR structure to the pname:pNext |
| chain of the slink:VkSemaphoreCreateInfo structure. |
| The sname:VkExportSemaphoreWin32HandleInfoKHR structure is defined as: |
| |
| include::{generated}/api/structs/VkExportSemaphoreWin32HandleInfoKHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:pAttributes is a pointer to a Windows code:SECURITY_ATTRIBUTES |
| structure specifying security attributes of the handle. |
| * pname:dwAccess is a code:DWORD specifying access rights of the handle. |
| * pname:name is a null-terminated UTF-16 string to associate with the |
| underlying synchronization primitive referenced by NT handles exported |
| from the created semaphore. |
| |
| If slink:VkExportSemaphoreCreateInfo is not included in the same pname:pNext |
| chain, this structure is ignored. |
| |
| If slink:VkExportSemaphoreCreateInfo is included in the pname:pNext chain of |
| slink:VkSemaphoreCreateInfo with a Windows pname:handleType, but either |
| sname:VkExportSemaphoreWin32HandleInfoKHR is not included in the pname:pNext |
| chain, or if it is but pname:pAttributes is set to `NULL`, default security |
| descriptor values will be used, and child processes created by the |
| application will not inherit the handle, as described in the MSDN |
| documentation for "`Synchronization Object Security and Access Rights`"^1^. |
| Further, if the structure is not present, the access rights used depend on |
| the handle type. |
| |
| For handles of the following types: |
| |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT |
| |
| The implementation must: ensure the access rights allow both signal and wait |
| operations on the semaphore. |
| |
| For handles of the following types: |
| |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT |
| |
| The access rights must: be: |
| |
| code:GENERIC_ALL |
| |
| 1:: |
| https://docs.microsoft.com/en-us/windows/win32/sync/synchronization-object-security-and-access-rights |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkExportSemaphoreWin32HandleInfoKHR-handleTypes-01125]] |
| If slink:VkExportSemaphoreCreateInfo::pname:handleTypes does not include |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT or |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, |
| sname:VkExportSemaphoreWin32HandleInfoKHR must: not be included in the |
| pname:pNext chain of slink:VkSemaphoreCreateInfo |
| **** |
| |
| include::{generated}/validity/structs/VkExportSemaphoreWin32HandleInfoKHR.txt[] |
| -- |
| |
| [open,refpage='vkGetSemaphoreWin32HandleKHR',desc='Get a Windows HANDLE for a semaphore',type='protos'] |
| -- |
| To export a Windows handle representing the payload of a semaphore, call: |
| |
| include::{generated}/api/protos/vkGetSemaphoreWin32HandleKHR.txt[] |
| |
| * pname:device is the logical device that created the semaphore being |
| exported. |
| * pname:pGetWin32HandleInfo is a pointer to a |
| slink:VkSemaphoreGetWin32HandleInfoKHR structure containing parameters |
| of the export operation. |
| * pname:pHandle will return the Windows handle representing the semaphore |
| state. |
| |
| For handle types defined as NT handles, the handles returned by |
| fname:vkGetSemaphoreWin32HandleKHR are owned by the application. |
| To avoid leaking resources, the application must: release ownership of them |
| using the code:CloseHandle system call when they are no longer needed. |
| |
| Exporting a Windows handle from a semaphore may: have side effects depending |
| on the transference of the specified handle type, as described in |
| <<synchronization-semaphores-importing,Importing Semaphore Payloads>>. |
| |
| include::{generated}/validity/protos/vkGetSemaphoreWin32HandleKHR.txt[] |
| -- |
| |
| [open,refpage='VkSemaphoreGetWin32HandleInfoKHR',desc='Structure describing a Win32 handle semaphore export operation',type='structs'] |
| -- |
| The sname:VkSemaphoreGetWin32HandleInfoKHR structure is defined as: |
| |
| include::{generated}/api/structs/VkSemaphoreGetWin32HandleInfoKHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:semaphore is the semaphore from which state will be exported. |
| * pname:handleType is a elink:VkExternalSemaphoreHandleTypeFlagBits value |
| specifying the type of handle requested. |
| |
| The properties of the handle returned depend on the value of |
| pname:handleType. |
| See elink:VkExternalSemaphoreHandleTypeFlagBits for a description of the |
| properties of the defined external semaphore handle types. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01126]] |
| pname:handleType must: have been included in |
| slink:VkExportSemaphoreCreateInfo::pname:handleTypes when the |
| pname:semaphore's current payload was created |
| * [[VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01127]] |
| If pname:handleType is defined as an NT handle, |
| flink:vkGetSemaphoreWin32HandleKHR must: be called no more than once for |
| each valid unique combination of pname:semaphore and pname:handleType |
| * [[VUID-VkSemaphoreGetWin32HandleInfoKHR-semaphore-01128]] |
| pname:semaphore must: not currently have its payload replaced by an |
| imported payload as described below in |
| <<synchronization-semaphores-importing,Importing Semaphore Payloads>> |
| unless that imported payload's handle type was included in |
| slink:VkExternalSemaphoreProperties::pname:exportFromImportedHandleTypes |
| for pname:handleType |
| * [[VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01129]] |
| If pname:handleType refers to a handle type with copy payload |
| transference semantics, as defined below in |
| <<synchronization-semaphores-importing,Importing Semaphore Payloads>>, |
| there must: be no queue waiting on pname:semaphore |
| * [[VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01130]] |
| If pname:handleType refers to a handle type with copy payload |
| transference semantics, pname:semaphore must: be signaled, or have an |
| associated <<synchronization-semaphores-signaling,semaphore signal |
| operation>> pending execution |
| * [[VUID-VkSemaphoreGetWin32HandleInfoKHR-handleType-01131]] |
| pname:handleType must: be defined as an NT handle or a global share |
| handle |
| **** |
| |
| include::{generated}/validity/structs/VkSemaphoreGetWin32HandleInfoKHR.txt[] |
| -- |
| endif::VK_KHR_external_semaphore_win32[] |
| |
| ifdef::VK_KHR_external_semaphore_fd[] |
| [open,refpage='vkGetSemaphoreFdKHR',desc='Get a POSIX file descriptor handle for a semaphore',type='protos'] |
| -- |
| To export a POSIX file descriptor representing the payload of a semaphore, |
| call: |
| |
| include::{generated}/api/protos/vkGetSemaphoreFdKHR.txt[] |
| |
| * pname:device is the logical device that created the semaphore being |
| exported. |
| * pname:pGetFdInfo is a pointer to a slink:VkSemaphoreGetFdInfoKHR |
| structure containing parameters of the export operation. |
| * pname:pFd will return the file descriptor representing the semaphore |
| payload. |
| |
| Each call to fname:vkGetSemaphoreFdKHR must: create a new file descriptor |
| and transfer ownership of it to the application. |
| To avoid leaking resources, the application must: release ownership of the |
| file descriptor when it is no longer needed. |
| |
| [NOTE] |
| .Note |
| ==== |
| Ownership can be released in many ways. |
| For example, the application can call code:close() on the file descriptor, |
| or transfer ownership back to Vulkan by using the file descriptor to import |
| a semaphore payload. |
| ==== |
| Where supported by the operating system, the implementation must: set the |
| file descriptor to be closed automatically when an code:execve system call |
| is made. |
| |
| Exporting a file descriptor from a semaphore may: have side effects |
| depending on the transference of the specified handle type, as described in |
| <<synchronization-semaphores-importing,Importing Semaphore State>>. |
| |
| include::{generated}/validity/protos/vkGetSemaphoreFdKHR.txt[] |
| -- |
| |
| [open,refpage='VkSemaphoreGetFdInfoKHR',desc='Structure describing a POSIX FD semaphore export operation',type='structs'] |
| -- |
| The sname:VkSemaphoreGetFdInfoKHR structure is defined as: |
| |
| include::{generated}/api/structs/VkSemaphoreGetFdInfoKHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:semaphore is the semaphore from which state will be exported. |
| * pname:handleType is a elink:VkExternalSemaphoreHandleTypeFlagBits value |
| specifying the type of handle requested. |
| |
| The properties of the file descriptor returned depend on the value of |
| pname:handleType. |
| See elink:VkExternalSemaphoreHandleTypeFlagBits for a description of the |
| properties of the defined external semaphore handle types. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkSemaphoreGetFdInfoKHR-handleType-01132]] |
| pname:handleType must: have been included in |
| slink:VkExportSemaphoreCreateInfo::pname:handleTypes when |
| pname:semaphore's current payload was created |
| * [[VUID-VkSemaphoreGetFdInfoKHR-semaphore-01133]] |
| pname:semaphore must: not currently have its payload replaced by an |
| imported payload as described below in |
| <<synchronization-semaphores-importing,Importing Semaphore Payloads>> |
| unless that imported payload's handle type was included in |
| slink:VkExternalSemaphoreProperties::pname:exportFromImportedHandleTypes |
| for pname:handleType |
| * [[VUID-VkSemaphoreGetFdInfoKHR-handleType-01134]] |
| If pname:handleType refers to a handle type with copy payload |
| transference semantics, as defined below in |
| <<synchronization-semaphores-importing,Importing Semaphore Payloads>>, |
| there must: be no queue waiting on pname:semaphore |
| * [[VUID-VkSemaphoreGetFdInfoKHR-handleType-01135]] |
| If pname:handleType refers to a handle type with copy payload |
| transference semantics, pname:semaphore must: be signaled, or have an |
| associated <<synchronization-semaphores-signaling,semaphore signal |
| operation>> pending execution |
| * [[VUID-VkSemaphoreGetFdInfoKHR-handleType-01136]] |
| pname:handleType must: be defined as a POSIX file descriptor handle |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| * [[VUID-VkSemaphoreGetFdInfoKHR-handleType-03253]] |
| If pname:handleType refers to a handle type with copy payload |
| transference semantics, pname:semaphore must: have been created with a |
| elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_BINARY |
| * [[VUID-VkSemaphoreGetFdInfoKHR-handleType-03254]] |
| If pname:handleType refers to a handle type with copy payload |
| transference semantics, pname:semaphore must: have an associated |
| semaphore signal operation that has been submitted for execution and any |
| semaphore signal operations on which it depends (if any) must: have also |
| been submitted for execution |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| **** |
| |
| include::{generated}/validity/structs/VkSemaphoreGetFdInfoKHR.txt[] |
| -- |
| endif::VK_KHR_external_semaphore_fd[] |
| |
| ifdef::VK_FUCHSIA_external_semaphore[] |
| [open,refpage='vkGetSemaphoreZirconHandleFUCHSIA',desc='Get a Zircon event handle for a semaphore',type='protos'] |
| -- |
| To export a Zircon event handle representing the payload of a semaphore, |
| call: |
| |
| include::{generated}/api/protos/vkGetSemaphoreZirconHandleFUCHSIA.txt[] |
| |
| * pname:device is the logical device that created the semaphore being |
| exported. |
| * pname:pGetZirconHandleInfo is a pointer to a |
| slink:VkSemaphoreGetZirconHandleInfoFUCHSIA structure containing |
| parameters of the export operation. |
| * pname:pZirconHandle will return the Zircon event handle representing the |
| semaphore payload. |
| |
| Each call to fname:vkGetSemaphoreZirconHandleFUCHSIA must: create a Zircon |
| event handle and transfer ownership of it to the application. |
| To avoid leaking resources, the application must: release ownership of the |
| Zircon event handle when it is no longer needed. |
| |
| [NOTE] |
| .Note |
| ==== |
| Ownership can be released in many ways. |
| For example, the application can call zx_handle_close() on the file |
| descriptor, or transfer ownership back to Vulkan by using the file |
| descriptor to import a semaphore payload. |
| ==== |
| |
| Exporting a Zircon event handle from a semaphore may: have side effects |
| depending on the transference of the specified handle type, as described in |
| <<synchronization-semaphores-importing,Importing Semaphore State>>. |
| |
| include::{generated}/validity/protos/vkGetSemaphoreZirconHandleFUCHSIA.txt[] |
| -- |
| |
| [open,refpage='VkSemaphoreGetZirconHandleInfoFUCHSIA',desc='Structure describing a Zircon event handle semaphore export operation',type='structs'] |
| -- |
| The sname:VkSemaphoreGetZirconHandleInfoFUCHSIA structure is defined as: |
| |
| include::{generated}/api/structs/VkSemaphoreGetZirconHandleInfoFUCHSIA.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:semaphore is the semaphore from which state will be exported. |
| * pname:handleType is a elink:VkExternalSemaphoreHandleTypeFlagBits value |
| specifying the type of handle requested. |
| |
| The properties of the Zircon event handle returned depend on the value of |
| pname:handleType. |
| See elink:VkExternalSemaphoreHandleTypeFlagBits for a description of the |
| properties of the defined external semaphore handle types. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkSemaphoreGetZirconHandleInfoFUCHSIA-handleType-04758]] |
| pname:handleType must: have been included in |
| slink:VkExportSemaphoreCreateInfo::pname:handleTypes when |
| pname:semaphore's current payload was created |
| * [[VUID-VkSemaphoreGetZirconHandleInfoFUCHSIA-semaphore-04759]] |
| pname:semaphore must: not currently have its payload replaced by an |
| imported payload as described below in |
| <<synchronization-semaphores-importing,Importing Semaphore Payloads>> |
| unless that imported payload's handle type was included in |
| slink:VkExternalSemaphoreProperties::pname:exportFromImportedHandleTypes |
| for pname:handleType |
| * [[VUID-VkSemaphoreGetZirconHandleInfoFUCHSIA-handleType-04760]] |
| If pname:handleType refers to a handle type with copy payload |
| transference semantics, as defined below in |
| <<synchronization-semaphores-importing,Importing Semaphore Payloads>>, |
| there must: be no queue waiting on pname:semaphore |
| * [[VUID-VkSemaphoreGetZirconHandleInfoFUCHSIA-handleType-04761]] |
| If pname:handleType refers to a handle type with copy payload |
| transference semantics, pname:semaphore must: be signaled, or have an |
| associated <<synchronization-semaphores-signaling,semaphore signal |
| operation>> pending execution |
| * [[VUID-VkSemaphoreGetZirconHandleInfoFUCHSIA-handleType-04762]] |
| pname:handleType must: be defined as a Zircon event handle |
| * [[VUID-VkSemaphoreGetZirconHandleInfoFUCHSIA-semaphore-04763]] |
| pname:semaphore must: have been created with a elink:VkSemaphoreType of |
| ename:VK_SEMAPHORE_TYPE_BINARY |
| **** |
| |
| include::{generated}/validity/structs/VkSemaphoreGetZirconHandleInfoFUCHSIA.txt[] |
| -- |
| endif::VK_FUCHSIA_external_semaphore[] |
| |
| [open,refpage='vkDestroySemaphore',desc='Destroy a semaphore object',type='protos'] |
| -- |
| To destroy a semaphore, call: |
| |
| include::{generated}/api/protos/vkDestroySemaphore.txt[] |
| |
| * pname:device is the logical device that destroys the semaphore. |
| * pname:semaphore is the handle of the semaphore to destroy. |
| * pname:pAllocator controls host memory allocation as described in the |
| <<memory-allocation, Memory Allocation>> chapter. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkDestroySemaphore-semaphore-01137]] |
| All submitted batches that refer to pname:semaphore must: have completed |
| execution |
| * [[VUID-vkDestroySemaphore-semaphore-01138]] |
| If sname:VkAllocationCallbacks were provided when pname:semaphore was |
| created, a compatible set of callbacks must: be provided here |
| * [[VUID-vkDestroySemaphore-semaphore-01139]] |
| If no sname:VkAllocationCallbacks were provided when pname:semaphore was |
| created, pname:pAllocator must: be `NULL` |
| **** |
| |
| include::{generated}/validity/protos/vkDestroySemaphore.txt[] |
| -- |
| |
| |
| [[synchronization-semaphores-signaling]] |
| === Semaphore Signaling |
| |
| When a batch is submitted to a queue via a <<devsandqueues-submission, queue |
| submission>>, and it includes semaphores to be signaled, it defines a memory |
| dependency on the batch, and defines _semaphore signal operations_ which set |
| the semaphores to the signaled state. |
| |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| In case of semaphores created with a elink:VkSemaphoreType of |
| ename:VK_SEMAPHORE_TYPE_TIMELINE the semaphore is considered signaled with |
| respect to the counter value set to be signaled as specified in |
| slink:VkTimelineSemaphoreSubmitInfo or slink:VkSemaphoreSignalInfo. |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> |
| includes every command submitted in the same batch. |
| ifdef::VK_KHR_synchronization2[] |
| In the case of flink:vkQueueSubmit2KHR, the first synchronization scope is |
| limited to the pipeline stage specified by |
| slink:VkSemaphoreSubmitInfoKHR::pname:stageMask. |
| endif::VK_KHR_synchronization2[] |
| Semaphore signal operations that are defined by flink:vkQueueSubmit |
| ifdef::VK_KHR_synchronization2[] |
| or flink:vkQueueSubmit2KHR |
| endif::VK_KHR_synchronization2[] |
| additionally include all commands that occur earlier in |
| <<synchronization-submission-order,submission order>>. |
| Semaphore signal operations that are defined by flink:vkQueueSubmit or |
| flink:vkQueueBindSparse additionally include in the first synchronization |
| scope any semaphore and fence signal operations that occur earlier in |
| <<synchronization-signal-operation-order,signal operation order>>. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| includes only the semaphore signal operation. |
| |
| The first <<synchronization-dependencies-access-scopes, access scope>> |
| includes all memory access performed by the device. |
| |
| The second <<synchronization-dependencies-access-scopes, access scope>> is |
| empty. |
| |
| |
| [[synchronization-semaphores-waiting]] |
| === Semaphore Waiting |
| |
| When a batch is submitted to a queue via a <<devsandqueues-submission, queue |
| submission>>, and it includes semaphores to be waited on, it defines a |
| memory dependency between prior semaphore signal operations and the batch, |
| and defines _semaphore wait operations_. |
| |
| Such semaphore wait operations set the semaphores |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| created with a elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_BINARY |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| to the unsignaled state. |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| In case of semaphores created with a elink:VkSemaphoreType of |
| ename:VK_SEMAPHORE_TYPE_TIMELINE a prior semaphore signal operation defines |
| a memory dependency with a semaphore wait operation if the value the |
| semaphore is signaled with is greater than or equal to the value the |
| semaphore is waited with, thus the semaphore will continue to be considered |
| signaled with respect to the counter value waited on as specified in |
| slink:VkTimelineSemaphoreSubmitInfo. |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| |
| The first synchronization scope includes all semaphore signal operations |
| that operate on semaphores waited on in the same batch, and that |
| happen-before the wait completes. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| includes every command submitted in the same batch. |
| In the case of flink:vkQueueSubmit, the second synchronization scope is |
| limited to operations on the pipeline stages determined by the |
| <<synchronization-pipeline-stages-masks, destination stage mask>> specified |
| by the corresponding element of pname:pWaitDstStageMask. |
| ifdef::VK_KHR_synchronization2[] |
| In the case of flink:vkQueueSubmit2KHR, the second synchronization scope is |
| limited to the pipeline stage specified by |
| slink:VkSemaphoreSubmitInfoKHR::pname:stageMask. |
| endif::VK_KHR_synchronization2[] |
| Also, in the case of |
| ifdef::VK_KHR_synchronization2[] |
| either flink:vkQueueSubmit2KHR or |
| endif::VK_KHR_synchronization2[] |
| flink:vkQueueSubmit, the second synchronization scope additionally includes |
| all commands that occur later in |
| <<synchronization-submission-order,submission order>>. |
| |
| The first <<synchronization-dependencies-access-scopes, access scope>> is |
| empty. |
| |
| The second <<synchronization-dependencies-access-scopes, access scope>> |
| includes all memory access performed by the device. |
| |
| The semaphore wait operation happens-after the first set of operations in |
| the execution dependency, and happens-before the second set of operations in |
| the execution dependency. |
| |
| [NOTE] |
| .Note |
| ==== |
| Unlike |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| timeline semaphores, |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| fences or events, the act of waiting for a binary semaphore also unsignals |
| that semaphore. |
| Applications must: ensure that between two such wait operations, the |
| semaphore is signaled again, with execution dependencies used to ensure |
| these occur in order. |
| Binary semaphore waits and signals should thus occur in discrete 1:1 pairs. |
| ==== |
| |
| ifdef::VK_KHR_swapchain[] |
| [NOTE] |
| .Note |
| ==== |
| A common scenario for using pname:pWaitDstStageMask with values other than |
| ename:VK_PIPELINE_STAGE_ALL_COMMANDS_BIT is when synchronizing a window |
| system presentation operation against subsequent command buffers which |
| render the next frame. |
| In this case, a presentation image must: not be overwritten until the |
| presentation operation completes, but other pipeline stages can: execute |
| without waiting. |
| A mask of ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT prevents |
| subsequent color attachment writes from executing until the semaphore |
| signals. |
| Some implementations may: be able to execute transfer operations and/or |
| pre-rasterization work before the semaphore is signaled. |
| |
| If an image layout transition needs to be performed on a presentable image |
| before it is used in a framebuffer, that can: be performed as the first |
| operation submitted to the queue after acquiring the image, and should: not |
| prevent other work from overlapping with the presentation operation. |
| For example, a sname:VkImageMemoryBarrier could use: |
| |
| * pname:srcStageMask = ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
| * pname:srcAccessMask = 0 |
| * pname:dstStageMask = ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
| * pname:dstAccessMask = ename:VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | |
| ename:VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT. |
| * pname:oldLayout = ename:VK_IMAGE_LAYOUT_PRESENT_SRC_KHR |
| * pname:newLayout = ename:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL |
| |
| Alternatively, pname:oldLayout can: be ename:VK_IMAGE_LAYOUT_UNDEFINED, if |
| the image's contents need not be preserved. |
| |
| This barrier accomplishes a dependency chain between previous presentation |
| operations and subsequent color attachment output operations, with the |
| layout transition performed in between, and does not introduce a dependency |
| between previous work and any |
| <<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>>s. |
| More precisely, the semaphore signals after the presentation operation |
| completes, the semaphore wait stalls the |
| ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT stage, and there is a |
| dependency from that same stage to itself with the layout transition |
| performed in between. |
| ==== |
| endif::VK_KHR_swapchain[] |
| |
| |
| [[synchronization-semaphores-waiting-state]] |
| === Semaphore State Requirements For Wait Operations |
| |
| Before waiting on a semaphore, the application must: ensure the semaphore is |
| in a valid state for a wait operation. |
| Specifically, when a <<synchronization-semaphores-waiting,semaphore wait |
| operation>> is submitted to a queue: |
| |
| * A binary semaphore must: be signaled, or have an associated |
| <<synchronization-semaphores-signaling,semaphore signal operation>> that |
| is pending execution. |
| * Any <<synchronization-semaphores-signaling,semaphore signal operations>> |
| on which the pending binary semaphore signal operation depends must: |
| also be completed or pending execution. |
| * There must: be no other queue waiting on the same binary semaphore when |
| the operation executes. |
| |
| |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| [[synchronization-semaphores-hostops]] |
| === Host Operations on Semaphores |
| |
| In addition to <<synchronization-semaphores-signaling,semaphore signal |
| operations>> and <<synchronization-semaphores-waiting,semaphore wait |
| operations>> submitted to device queues, timeline semaphores support the |
| following host operations: |
| |
| * Query the current counter value of the semaphore using the |
| flink:vkGetSemaphoreCounterValue command. |
| * Wait for a set of semaphores to reach particular counter values using |
| the flink:vkWaitSemaphores command. |
| * Signal the semaphore with a particular counter value from the host using |
| the flink:vkSignalSemaphore command. |
| |
| [open,refpage='vkGetSemaphoreCounterValue',desc='Query the current state of a timeline semaphore',type='protos',alias='vkGetSemaphoreCounterValueKHR'] |
| -- |
| To query the current counter value of a semaphore created with a |
| elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_TIMELINE from the host, |
| call: |
| |
| ifdef::VK_VERSION_1_2[] |
| include::{generated}/api/protos/vkGetSemaphoreCounterValue.txt[] |
| endif::VK_VERSION_1_2[] |
| |
| ifdef::VK_VERSION_1_2+VK_KHR_timeline_semaphore[or the equivalent command] |
| |
| ifdef::VK_KHR_timeline_semaphore[] |
| include::{generated}/api/protos/vkGetSemaphoreCounterValueKHR.txt[] |
| endif::VK_KHR_timeline_semaphore[] |
| |
| * pname:device is the logical device that owns the semaphore. |
| * pname:semaphore is the handle of the semaphore to query. |
| * pname:pValue is a pointer to a 64-bit integer value in which the current |
| counter value of the semaphore is returned. |
| |
| [NOTE] |
| .Note |
| ==== |
| If a <<devsandqueues-submission, queue submission>> command is pending |
| execution, then the value returned by this command may: immediately be out |
| of date. |
| ==== |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkGetSemaphoreCounterValue-semaphore-03255]] |
| pname:semaphore must: have been created with a elink:VkSemaphoreType of |
| ename:VK_SEMAPHORE_TYPE_TIMELINE |
| **** |
| |
| include::{generated}/validity/protos/vkGetSemaphoreCounterValue.txt[] |
| -- |
| |
| [open,refpage='vkWaitSemaphores',desc='Wait for timeline semaphores on the host',type='protos',alias='vkWaitSemaphoresKHR'] |
| -- |
| To wait for a set of semaphores created with a elink:VkSemaphoreType of |
| ename:VK_SEMAPHORE_TYPE_TIMELINE to reach particular counter values on the |
| host, call: |
| |
| ifdef::VK_VERSION_1_2[] |
| include::{generated}/api/protos/vkWaitSemaphores.txt[] |
| endif::VK_VERSION_1_2[] |
| |
| ifdef::VK_VERSION_1_2+VK_KHR_timeline_semaphore[or the equivalent command] |
| |
| ifdef::VK_KHR_timeline_semaphore[] |
| include::{generated}/api/protos/vkWaitSemaphoresKHR.txt[] |
| endif::VK_KHR_timeline_semaphore[] |
| |
| * pname:device is the logical device that owns the semaphores. |
| * pname:pWaitInfo is a pointer to a slink:VkSemaphoreWaitInfo structure |
| containing information about the wait condition. |
| * pname:timeout is the timeout period in units of nanoseconds. |
| pname:timeout is adjusted to the closest value allowed by the |
| implementation-dependent timeout accuracy, which may: be substantially |
| longer than one nanosecond, and may: be longer than the requested |
| period. |
| |
| If the condition is satisfied when fname:vkWaitSemaphores is called, then |
| fname:vkWaitSemaphores returns immediately. |
| If the condition is not satisfied at the time fname:vkWaitSemaphores is |
| called, then fname:vkWaitSemaphores will block and wait until the condition |
| is satisfied or the pname:timeout has expired, whichever is sooner. |
| |
| If pname:timeout is zero, then fname:vkWaitSemaphores does not wait, but |
| simply returns information about the current state of the semaphores. |
| ename:VK_TIMEOUT will be returned in this case if the condition is not |
| satisfied, even though no actual wait was performed. |
| |
| If the condition is satisfied before the pname:timeout has expired, |
| fname:vkWaitSemaphores returns ename:VK_SUCCESS. |
| Otherwise, fname:vkWaitSemaphores returns ename:VK_TIMEOUT after the |
| pname:timeout has expired. |
| |
| If device loss occurs (see <<devsandqueues-lost-device,Lost Device>>) before |
| the timeout has expired, fname:vkWaitSemaphores must: return in finite time |
| with either ename:VK_SUCCESS or ename:VK_ERROR_DEVICE_LOST. |
| |
| include::{generated}/validity/protos/vkWaitSemaphores.txt[] |
| -- |
| |
| [open,refpage='VkSemaphoreWaitInfo',desc='Structure containing information about the semaphore wait condition',type='structs',alias='VkSemaphoreWaitInfoKHR'] |
| -- |
| The sname:VkSemaphoreWaitInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkSemaphoreWaitInfo.txt[] |
| |
| ifdef::VK_KHR_timeline_semaphore[] |
| or the equivalent |
| |
| include::{generated}/api/structs/VkSemaphoreWaitInfoKHR.txt[] |
| endif::VK_KHR_timeline_semaphore[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:flags is a bitmask of elink:VkSemaphoreWaitFlagBits specifying |
| additional parameters for the semaphore wait operation. |
| * pname:semaphoreCount is the number of semaphores to wait on. |
| * pname:pSemaphores is a pointer to an array of pname:semaphoreCount |
| semaphore handles to wait on. |
| * pname:pValues is a pointer to an array of pname:semaphoreCount timeline |
| semaphore values. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkSemaphoreWaitInfo-pSemaphores-03256]] |
| All of the elements of pname:pSemaphores must: reference a semaphore |
| that was created with a elink:VkSemaphoreType of |
| ename:VK_SEMAPHORE_TYPE_TIMELINE |
| **** |
| |
| include::{generated}/validity/structs/VkSemaphoreWaitInfo.txt[] |
| -- |
| |
| [open,refpage='VkSemaphoreWaitFlagBits',desc='Bitmask specifying additional parameters of a semaphore wait operation',type='enums',alias='VkSemaphoreWaitFlagBitsKHR'] |
| -- |
| Bits which can: be set in slink:VkSemaphoreWaitInfo::pname:flags, specifying |
| additional parameters of a semaphore wait operation, are: |
| |
| include::{generated}/api/enums/VkSemaphoreWaitFlagBits.txt[] |
| |
| ifdef::VK_KHR_timeline_semaphore[] |
| or the equivalent |
| |
| include::{generated}/api/enums/VkSemaphoreWaitFlagBitsKHR.txt[] |
| endif::VK_KHR_timeline_semaphore[] |
| |
| * ename:VK_SEMAPHORE_WAIT_ANY_BIT specifies that the semaphore wait |
| condition is that at least one of the semaphores in |
| sname:VkSemaphoreWaitInfo::pname:pSemaphores has reached the value |
| specified by the corresponding element of |
| sname:VkSemaphoreWaitInfo::pname:pValues. |
| If ename:VK_SEMAPHORE_WAIT_ANY_BIT is not set, the semaphore wait |
| condition is that all of the semaphores in |
| sname:VkSemaphoreWaitInfo::pname:pSemaphores have reached the value |
| specified by the corresponding element of |
| sname:VkSemaphoreWaitInfo::pname:pValues. |
| -- |
| |
| [open,refpage='VkSemaphoreWaitFlags',desc='Bitmask of VkSemaphoreWaitFlagBits',type='flags',alias='VkSemaphoreWaitFlagsKHR'] |
| -- |
| include::{generated}/api/flags/VkSemaphoreWaitFlags.txt[] |
| |
| ifdef::VK_KHR_timeline_semaphore[] |
| or the equivalent |
| |
| include::{generated}/api/flags/VkSemaphoreWaitFlagsKHR.txt[] |
| endif::VK_KHR_timeline_semaphore[] |
| |
| tname:VkSemaphoreWaitFlags is a bitmask type for setting a mask of zero or |
| more elink:VkSemaphoreWaitFlagBits. |
| -- |
| |
| [open,refpage='vkSignalSemaphore',desc='Signal a timeline semaphore on the host',type='protos',alias='vkSignalSemaphoreKHR'] |
| -- |
| To signal a semaphore created with a elink:VkSemaphoreType of |
| ename:VK_SEMAPHORE_TYPE_TIMELINE with a particular counter value, on the |
| host, call: |
| |
| ifdef::VK_VERSION_1_2[] |
| include::{generated}/api/protos/vkSignalSemaphore.txt[] |
| endif::VK_VERSION_1_2[] |
| |
| ifdef::VK_VERSION_1_2+VK_KHR_timeline_semaphore[or the equivalent command] |
| |
| ifdef::VK_KHR_timeline_semaphore[] |
| include::{generated}/api/protos/vkSignalSemaphoreKHR.txt[] |
| endif::VK_KHR_timeline_semaphore[] |
| |
| * pname:device is the logical device that owns the semaphore. |
| * pname:pSignalInfo is a pointer to a slink:VkSemaphoreSignalInfo |
| structure containing information about the signal operation. |
| |
| When fname:vkSignalSemaphore is executed on the host, it defines and |
| immediately executes a <<synchronization-semaphores-signaling,_semaphore |
| signal operation_>> which sets the timeline semaphore to the given value. |
| |
| The first synchronization scope is defined by the host execution model, but |
| includes execution of fname:vkSignalSemaphore on the host and anything that |
| happened-before it. |
| |
| The second synchronization scope is empty. |
| |
| include::{generated}/validity/protos/vkSignalSemaphore.txt[] |
| -- |
| |
| [open,refpage='VkSemaphoreSignalInfo',desc='Structure containing information about a semaphore signal operation',type='structs',alias='VkSemaphoreSignalInfoKHR'] |
| -- |
| The sname:VkSemaphoreSignalInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkSemaphoreSignalInfo.txt[] |
| |
| ifdef::VK_KHR_timeline_semaphore[] |
| or the equivalent |
| |
| include::{generated}/api/structs/VkSemaphoreSignalInfoKHR.txt[] |
| endif::VK_KHR_timeline_semaphore[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:semaphore is the handle of the semaphore to signal. |
| * pname:value is the value to signal. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkSemaphoreSignalInfo-semaphore-03257]] |
| pname:semaphore must: have been created with a elink:VkSemaphoreType of |
| ename:VK_SEMAPHORE_TYPE_TIMELINE |
| * [[VUID-VkSemaphoreSignalInfo-value-03258]] |
| pname:value must: have a value greater than the current value of the |
| semaphore |
| * [[VUID-VkSemaphoreSignalInfo-value-03259]] |
| pname:value must: be less than the value of any pending semaphore signal |
| operations |
| * [[VUID-VkSemaphoreSignalInfo-value-03260]] |
| pname:value must: have a value which does not differ from the current |
| value of the semaphore or the value of any outstanding semaphore wait or |
| signal operation on pname:semaphore by more than |
| <<limits-maxTimelineSemaphoreValueDifference, |
| pname:maxTimelineSemaphoreValueDifference>> |
| **** |
| |
| include::{generated}/validity/structs/VkSemaphoreSignalInfo.txt[] |
| -- |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_semaphore[] |
| [[synchronization-semaphores-importing]] |
| === Importing Semaphore Payloads |
| |
| Applications can: import a semaphore payload into an existing semaphore |
| using an external semaphore handle. |
| The effects of the import operation will be either temporary or permanent, |
| as specified by the application. |
| If the import is temporary, the implementation must: restore the semaphore |
| to its prior permanent state after submitting the next semaphore wait |
| operation. |
| Performing a subsequent temporary import on a semaphore before performing a |
| semaphore wait has no effect on this requirement; the next wait submitted on |
| the semaphore must: still restore its last permanent state. |
| A permanent payload import behaves as if the target semaphore was destroyed, |
| and a new semaphore was created with the same handle but the imported |
| payload. |
| Because importing a semaphore payload temporarily or permanently detaches |
| the existing payload from a semaphore, similar usage restrictions to those |
| applied to fname:vkDestroySemaphore are applied to any command that imports |
| a semaphore payload. |
| Which of these import types is used is referred to as the import operation's |
| _permanence_. |
| Each handle type supports either one or both types of permanence. |
| |
| The implementation must: perform the import operation by either referencing |
| or copying the payload referred to by the specified external semaphore |
| handle, depending on the handle's type. |
| The import method used is referred to as the handle type's _transference_. |
| When using handle types with reference transference, importing a payload to |
| a semaphore adds the semaphore to the set of all semaphores sharing that |
| payload. |
| This set includes the semaphore from which the payload was exported. |
| Semaphore signaling and waiting operations performed on any semaphore in the |
| set must: behave as if the set were a single semaphore. |
| Importing a payload using handle types with copy transference creates a |
| duplicate copy of the payload at the time of import, but makes no further |
| reference to it. |
| Semaphore signaling and waiting operations performed on the target of copy |
| imports must: not affect any other semaphore or payload. |
| |
| Export operations have the same transference as the specified handle type's |
| import operations. |
| Additionally, exporting a semaphore payload to a handle with copy |
| transference has the same side effects on the source semaphore's payload as |
| executing a semaphore wait operation. |
| If the semaphore was using a temporarily imported payload, the semaphore's |
| prior permanent payload will be restored. |
| |
| ifdef::VK_KHR_external_semaphore_win32,VK_KHR_external_semaphore_fd,VK_FUCHSIA_external_semaphore[] |
| [NOTE] |
| .Note |
| ==== |
| The permanence and transference of handle types can be found in: |
| |
| ifdef::VK_KHR_external_semaphore_win32[] |
| * <<synchronization-semaphore-handletypes-win32,Handle Types Supported by |
| sname:VkImportSemaphoreWin32HandleInfoKHR>> |
| endif::VK_KHR_external_semaphore_win32[] |
| ifdef::VK_KHR_external_semaphore_fd[] |
| * <<synchronization-semaphore-handletypes-fd,Handle Types Supported by |
| sname:VkImportSemaphoreFdInfoKHR>> |
| endif::VK_KHR_external_semaphore_fd[] |
| ifdef::VK_FUCHSIA_external_semaphore[] |
| * <<synchronization-semaphore-handletypes-fuchsia,Handle Types Supported |
| by sname:VkImportSemaphoreZirconHandleInfoFUCHSIA>> |
| endif::VK_FUCHSIA_external_semaphore[] |
| ==== |
| endif::VK_KHR_external_semaphore_win32,VK_KHR_external_semaphore_fd,VK_FUCHSIA_external_semaphore[] |
| |
| <<fundamentals-threadingbehavior,External synchronization>> allows |
| implementations to modify an object's internal state, i.e. payload, without |
| internal synchronization. |
| However, for semaphores sharing a payload across processes, satisfying the |
| external synchronization requirements of sname:VkSemaphore parameters as if |
| all semaphores in the set were the same object is sometimes infeasible. |
| Satisfying the <<synchronization-semaphores-waiting-state,wait operation |
| state requirements>> would similarly require impractical coordination or |
| levels of trust between processes. |
| Therefore, these constraints only apply to a specific semaphore handle, not |
| to its payload. |
| For distinct semaphore objects which share a payload, if the semaphores are |
| passed to separate queue submission commands concurrently, behavior will be |
| as if the commands were called in an arbitrary sequential order. |
| If the <<synchronization-semaphores-waiting-state,wait operation state |
| requirements>> are violated for the shared payload by a queue submission |
| command, or if a signal operation is queued for a shared payload that is |
| already signaled or has a pending signal operation, effects must: be limited |
| to one or more of the following: |
| |
| * Returning ename:VK_ERROR_INITIALIZATION_FAILED from the command which |
| resulted in the violation. |
| * Losing the logical device on which the violation occurred immediately or |
| at a future time, resulting in a ename:VK_ERROR_DEVICE_LOST error from |
| subsequent commands, including the one causing the violation. |
| * Continuing execution of the violating command or operation as if the |
| semaphore wait completed successfully after an implementation-dependent |
| timeout. |
| In this case, the state of the payload becomes undefined:, and future |
| operations on semaphores sharing the payload will be subject to these |
| same rules. |
| The semaphore must: be destroyed or have its payload replaced by an |
| import operation to again have a well-defined state. |
| |
| [NOTE] |
| .Note |
| ==== |
| These rules allow processes to synchronize access to shared memory without |
| trusting each other. |
| However, such processes must still be cautious not to use the shared |
| semaphore for more than synchronizing access to the shared memory. |
| For example, a process should not use a shared semaphore as part of an |
| execution dependency chain that, when complete, leads to objects being |
| destroyed, if it does not trust other processes sharing the semaphore |
| payload. |
| ==== |
| |
| When a semaphore is using an imported payload, its |
| slink:VkExportSemaphoreCreateInfo::pname:handleTypes value is that specified |
| when creating the semaphore from which the payload was exported, rather than |
| that specified when creating the semaphore. |
| Additionally, |
| slink:VkExternalSemaphoreProperties::pname:exportFromImportedHandleTypes |
| restricts which handle types can: be exported from such a semaphore based on |
| the specific handle type used to import the current payload. |
| ifdef::VK_KHR_swapchain[] |
| Passing a semaphore to flink:vkAcquireNextImageKHR is equivalent to |
| temporarily importing a semaphore payload to that semaphore. |
| |
| [NOTE] |
| .Note |
| ==== |
| Because the exportable handle types of an imported semaphore correspond to |
| its current imported payload, and flink:vkAcquireNextImageKHR behaves the |
| same as a temporary import operation for which the source semaphore is |
| opaque to the application, applications have no way of determining whether |
| any external handle types can: be exported from a semaphore in this state. |
| Therefore, applications must: not attempt to export external handles from |
| semaphores using a temporarily imported payload from |
| flink:vkAcquireNextImageKHR. |
| ==== |
| endif::VK_KHR_swapchain[] |
| |
| When importing a semaphore payload, it is the responsibility of the |
| application to ensure the external handles meet all valid usage |
| requirements. |
| However, implementations must: perform sufficient validation of external |
| handles to ensure that the operation results in a valid semaphore which will |
| not cause program termination, device loss, queue stalls, or corruption of |
| other resources when used as allowed according to its import parameters, and |
| excepting those side effects allowed for violations of the |
| <<synchronization-semaphores-waiting-state,valid semaphore state for wait |
| operations>> rules. |
| If the external handle provided does not meet these requirements, the |
| implementation must: fail the semaphore payload import operation with the |
| error code ename:VK_ERROR_INVALID_EXTERNAL_HANDLE. |
| |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| In addition, when importing a semaphore payload that is not compatible with |
| the payload type corresponding to the elink:VkSemaphoreType the semaphore |
| was created with, the implementation may: fail the semaphore payload import |
| operation with the error code ename:VK_ERROR_INVALID_EXTERNAL_HANDLE. |
| |
| [NOTE] |
| .Note |
| ==== |
| As the introduction of the external semaphore handle type |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT predates that of |
| timeline semaphores, support for importing semaphore payloads from external |
| handles of that type into semaphores created (implicitly or explicitly) with |
| a elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_BINARY is preserved for |
| backwards compatibility. |
| However, applications should: prefer importing such handle types into |
| semaphores created with a elink:VkSemaphoreType of |
| ename:VK_SEMAPHORE_TYPE_TIMELINE. |
| ==== |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| endif::VK_VERSION_1_1,VK_KHR_external_semaphore[] |
| |
| ifdef::VK_KHR_external_semaphore_win32[] |
| [open,refpage='vkImportSemaphoreWin32HandleKHR',desc='Import a semaphore from a Windows HANDLE',type='protos'] |
| -- |
| To import a semaphore payload from a Windows handle, call: |
| |
| include::{generated}/api/protos/vkImportSemaphoreWin32HandleKHR.txt[] |
| |
| * pname:device is the logical device that created the semaphore. |
| * pname:pImportSemaphoreWin32HandleInfo is a pointer to a |
| slink:VkImportSemaphoreWin32HandleInfoKHR structure specifying the |
| semaphore and import parameters. |
| |
| Importing a semaphore payload from Windows handles does not transfer |
| ownership of the handle to the Vulkan implementation. |
| For handle types defined as NT handles, the application must: release |
| ownership using the code:CloseHandle system call when the handle is no |
| longer needed. |
| |
| Applications can: import the same semaphore payload into multiple instances |
| of Vulkan, into the same instance from which it was exported, and multiple |
| times into a given Vulkan instance. |
| |
| include::{generated}/validity/protos/vkImportSemaphoreWin32HandleKHR.txt[] |
| -- |
| |
| [open,refpage='VkImportSemaphoreWin32HandleInfoKHR',desc='Structure specifying Windows handle to import to a semaphore',type='structs'] |
| -- |
| The sname:VkImportSemaphoreWin32HandleInfoKHR structure is defined as: |
| |
| include::{generated}/api/structs/VkImportSemaphoreWin32HandleInfoKHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:semaphore is the semaphore into which the payload will be |
| imported. |
| * pname:flags is a bitmask of elink:VkSemaphoreImportFlagBits specifying |
| additional parameters for the semaphore payload import operation. |
| * pname:handleType is a elink:VkExternalSemaphoreHandleTypeFlagBits value |
| specifying the type of pname:handle. |
| * pname:handle is `NULL` or the external handle to import. |
| * pname:name is `NULL` or a null-terminated UTF-16 string naming the |
| underlying synchronization primitive to import. |
| |
| The handle types supported by pname:handleType are: |
| |
| [[synchronization-semaphore-handletypes-win32]] |
| .Handle Types Supported by sname:VkImportSemaphoreWin32HandleInfoKHR |
| [width="80%",options="header"] |
| |==== |
| | Handle Type | Transference | Permanence Supported |
| | ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT | Reference | Temporary,Permanent |
| | ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT | Reference | Temporary,Permanent |
| | ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT | Reference | Temporary,Permanent |
| |==== |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handleType-01140]] |
| pname:handleType must: be a value included in the |
| <<synchronization-semaphore-handletypes-win32,Handle Types Supported by |
| sname:VkImportSemaphoreWin32HandleInfoKHR>> table |
| * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handleType-01466]] |
| If pname:handleType is not |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT or |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, pname:name |
| must: be `NULL` |
| * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handleType-01467]] |
| If pname:handle is `NULL`, pname:name must: name a valid synchronization |
| primitive of the type specified by pname:handleType |
| * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handleType-01468]] |
| If pname:name is `NULL`, pname:handle must: be a valid handle of the |
| type specified by pname:handleType |
| * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handle-01469]] |
| If pname:handle is not `NULL`, pname:name must: be `NULL` |
| * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handle-01542]] |
| If pname:handle is not `NULL`, it must: obey any requirements listed for |
| pname:handleType in |
| <<external-semaphore-handle-types-compatibility,external semaphore |
| handle types compatibility>> |
| * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-name-01543]] |
| If pname:name is not `NULL`, it must: obey any requirements listed for |
| pname:handleType in |
| <<external-semaphore-handle-types-compatibility,external semaphore |
| handle types compatibility>> |
| * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handleType-03261]] |
| If pname:handleType is |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT or |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, the |
| slink:VkSemaphoreCreateInfo::pname:flags field must: match that of the |
| semaphore from which pname:handle or pname:name was exported |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-handleType-03262]] |
| If pname:handleType is |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT or |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, the |
| slink:VkSemaphoreTypeCreateInfo::pname:semaphoreType field must: match |
| that of the semaphore from which pname:handle or pname:name was exported |
| * [[VUID-VkImportSemaphoreWin32HandleInfoKHR-flags-03322]] |
| If pname:flags contains ename:VK_SEMAPHORE_IMPORT_TEMPORARY_BIT, the |
| slink:VkSemaphoreTypeCreateInfo::pname:semaphoreType field of the |
| semaphore from which pname:handle or pname:name was exported must: not |
| be ename:VK_SEMAPHORE_TYPE_TIMELINE |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| **** |
| |
| include::{generated}/validity/structs/VkImportSemaphoreWin32HandleInfoKHR.txt[] |
| -- |
| endif::VK_KHR_external_semaphore_win32[] |
| |
| ifdef::VK_KHR_external_semaphore_fd[] |
| [open,refpage='vkImportSemaphoreFdKHR',desc='Import a semaphore from a POSIX file descriptor',type='protos'] |
| -- |
| To import a semaphore payload from a POSIX file descriptor, call: |
| |
| include::{generated}/api/protos/vkImportSemaphoreFdKHR.txt[] |
| |
| * pname:device is the logical device that created the semaphore. |
| * pname:pImportSemaphoreFdInfo is a pointer to a |
| slink:VkImportSemaphoreFdInfoKHR structure specifying the semaphore and |
| import parameters. |
| |
| Importing a semaphore payload from a file descriptor transfers ownership of |
| the file descriptor from the application to the Vulkan implementation. |
| The application must: not perform any operations on the file descriptor |
| after a successful import. |
| |
| Applications can: import the same semaphore payload into multiple instances |
| of Vulkan, into the same instance from which it was exported, and multiple |
| times into a given Vulkan instance. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkImportSemaphoreFdKHR-semaphore-01142]] |
| pname:semaphore must: not be associated with any queue command that has |
| not yet completed execution on that queue |
| **** |
| |
| include::{generated}/validity/protos/vkImportSemaphoreFdKHR.txt[] |
| -- |
| |
| [open,refpage='VkImportSemaphoreFdInfoKHR',desc='Structure specifying POSIX file descriptor to import to a semaphore',type='structs'] |
| -- |
| The sname:VkImportSemaphoreFdInfoKHR structure is defined as: |
| |
| include::{generated}/api/structs/VkImportSemaphoreFdInfoKHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:semaphore is the semaphore into which the payload will be |
| imported. |
| * pname:flags is a bitmask of elink:VkSemaphoreImportFlagBits specifying |
| additional parameters for the semaphore payload import operation. |
| * pname:handleType is a elink:VkExternalSemaphoreHandleTypeFlagBits value |
| specifying the type of pname:fd. |
| * pname:fd is the external handle to import. |
| |
| The handle types supported by pname:handleType are: |
| |
| [[synchronization-semaphore-handletypes-fd]] |
| .Handle Types Supported by sname:VkImportSemaphoreFdInfoKHR |
| [width="80%",options="header"] |
| |==== |
| | Handle Type | Transference | Permanence Supported |
| | ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT | Reference | Temporary,Permanent |
| | ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT | Copy | Temporary |
| |==== |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkImportSemaphoreFdInfoKHR-handleType-01143]] |
| pname:handleType must: be a value included in the |
| <<synchronization-semaphore-handletypes-fd,Handle Types Supported by |
| sname:VkImportSemaphoreFdInfoKHR>> table |
| * [[VUID-VkImportSemaphoreFdInfoKHR-fd-01544]] |
| pname:fd must: obey any requirements listed for pname:handleType in |
| <<external-semaphore-handle-types-compatibility,external semaphore |
| handle types compatibility>> |
| * [[VUID-VkImportSemaphoreFdInfoKHR-handleType-03263]] |
| If pname:handleType is |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT, the |
| slink:VkSemaphoreCreateInfo::pname:flags field must: match that of the |
| semaphore from which pname:fd was exported |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| * [[VUID-VkImportSemaphoreFdInfoKHR-handleType-03264]] |
| If pname:handleType is |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT, the |
| slink:VkSemaphoreTypeCreateInfo::pname:semaphoreType field must: match |
| that of the semaphore from which pname:fd was exported |
| * [[VUID-VkImportSemaphoreFdInfoKHR-flags-03323]] |
| If pname:flags contains ename:VK_SEMAPHORE_IMPORT_TEMPORARY_BIT, the |
| slink:VkSemaphoreTypeCreateInfo::pname:semaphoreType field of the |
| semaphore from which pname:fd was exported must: not be |
| ename:VK_SEMAPHORE_TYPE_TIMELINE |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| **** |
| |
| If pname:handleType is ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, |
| the special value `-1` for pname:fd is treated like a valid sync file |
| descriptor referring to an object that has already signaled. |
| The import operation will succeed and the sname:VkSemaphore will have a |
| temporarily imported payload as if a valid file descriptor had been |
| provided. |
| |
| [NOTE] |
| .Note |
| ==== |
| This special behavior for importing an invalid sync file descriptor allows |
| easier interoperability with other system APIs which use the convention that |
| an invalid sync file descriptor represents work that has already completed |
| and does not need to be waited for. |
| It is consistent with the option for implementations to return a `-1` file |
| descriptor when exporting a |
| ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT from a sname:VkSemaphore |
| which is signaled. |
| ==== |
| |
| include::{generated}/validity/structs/VkImportSemaphoreFdInfoKHR.txt[] |
| -- |
| endif::VK_KHR_external_semaphore_fd[] |
| |
| ifdef::VK_FUCHSIA_external_semaphore[] |
| [open,refpage='vkImportSemaphoreZirconHandleFUCHSIA',desc='Import a semaphore from a Zircon event handle',type='protos'] |
| -- |
| To import a semaphore payload from a Zircon event handle, call: |
| |
| include::{generated}/api/protos/vkImportSemaphoreZirconHandleFUCHSIA.txt[] |
| |
| * pname:device is the logical device that created the semaphore. |
| * pname:pImportSemaphoreZirconHandleInfo is a pointer to a |
| slink:VkImportSemaphoreZirconHandleInfoFUCHSIA structure specifying the |
| semaphore and import parameters. |
| |
| Importing a semaphore payload from a Zircon event handle transfers ownership |
| of the handle from the application to the Vulkan implementation. |
| The application must: not perform any operations on the handle after a |
| successful import. |
| |
| Applications can: import the same semaphore payload into multiple instances |
| of Vulkan, into the same instance from which it was exported, and multiple |
| times into a given Vulkan instance. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkImportSemaphoreZirconHandleFUCHSIA-semaphore-04764]] |
| pname:semaphore must: not be associated with any queue command that has |
| not yet completed execution on that queue |
| **** |
| |
| include::{generated}/validity/protos/vkImportSemaphoreZirconHandleFUCHSIA.txt[] |
| -- |
| |
| [open,refpage='VkImportSemaphoreZirconHandleInfoFUCHSIA',desc='Structure specifying Zircon event handle to import to a semaphore',type='structs'] |
| -- |
| The sname:VkImportSemaphoreZirconHandleInfoFUCHSIA structure is defined as: |
| |
| include::{generated}/api/structs/VkImportSemaphoreZirconHandleInfoFUCHSIA.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:semaphore is the semaphore into which the payload will be |
| imported. |
| * pname:flags is a bitmask of elink:VkSemaphoreImportFlagBits specifying |
| additional parameters for the semaphore payload import operation. |
| * pname:handleType is a elink:VkExternalSemaphoreHandleTypeFlagBits value |
| specifying the type of pname:zirconHandle. |
| * pname:zirconHandle is the external handle to import. |
| |
| The handle types supported by pname:handleType are: |
| |
| [[synchronization-semaphore-handletypes-fuchsia]] |
| .Handle Types Supported by sname:VkImportSemaphoreZirconHandleInfoFUCHSIA |
| [width="80%",options="header"] |
| |==== |
| | Handle Type | Transference | Permanence Supported |
| | ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA | Reference | Temporary,Permanent |
| |==== |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkImportSemaphoreZirconHandleInfoFUCHSIA-handleType-04765]] |
| pname:handleType must: be a value included in the |
| <<synchronization-semaphore-handletypes-fuchsia,Handle Types Supported |
| by sname:VkImportSemaphoreZirconHandleInfoFUCHSIA>> table |
| * [[VUID-VkImportSemaphoreZirconHandleInfoFUCHSIA-zirconHandle-04766]] |
| pname:zirconHandle must: obey any requirements listed for |
| pname:handleType in |
| <<external-semaphore-handle-types-compatibility,external semaphore |
| handle types compatibility>> |
| * [[VUID-VkImportSemaphoreZirconHandleInfoFUCHSIA-zirconHandle-04767]] |
| pname:zirconHandle must: have code:ZX_RIGHTS_BASIC and |
| code:ZX_RIGHTS_SIGNAL rights |
| ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| * [[VUID-VkImportSemaphoreZirconHandleInfoFUCHSIA-semaphoreType-04768]] |
| The slink:VkSemaphoreTypeCreateInfo::pname:semaphoreType field must: not |
| be ename:VK_SEMAPHORE_TYPE_TIMELINE |
| endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[] |
| **** |
| |
| include::{generated}/validity/structs/VkImportSemaphoreZirconHandleInfoFUCHSIA.txt[] |
| -- |
| endif::VK_FUCHSIA_external_semaphore[] |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_semaphore[] |
| ifdef::VK_KHR_external_semaphore_win32,VK_KHR_external_semaphore_fd,VK_FUCHSIA_external_semaphore[] |
| [open,refpage='VkSemaphoreImportFlagBits',desc='Bitmask specifying additional parameters of semaphore payload import',type='enums'] |
| -- |
| Bits which can: be set in |
| |
| ifdef::VK_KHR_external_semaphore_win32[] |
| * slink:VkImportSemaphoreWin32HandleInfoKHR::pname:flags |
| endif::VK_KHR_external_semaphore_win32[] |
| ifdef::VK_KHR_external_semaphore_fd[] |
| * slink:VkImportSemaphoreFdInfoKHR::pname:flags |
| endif::VK_KHR_external_semaphore_fd[] |
| ifdef::VK_FUCHSIA_external_semaphore[] |
| * slink:VkImportSemaphoreZirconHandleInfoFUCHSIA::pname:flags |
| endif::VK_FUCHSIA_external_semaphore[] |
| |
| specifying additional parameters of a semaphore import operation are: |
| |
| include::{generated}/api/enums/VkSemaphoreImportFlagBits.txt[] |
| |
| ifdef::VK_KHR_external_semaphore[] |
| or the equivalent |
| |
| include::{generated}/api/enums/VkSemaphoreImportFlagBitsKHR.txt[] |
| endif::VK_KHR_external_semaphore[] |
| |
| These bits have the following meanings: |
| |
| * ename:VK_SEMAPHORE_IMPORT_TEMPORARY_BIT specifies that the semaphore |
| payload will be imported only temporarily, as described in |
| <<synchronization-semaphores-importing,Importing Semaphore Payloads>>, |
| regardless of the permanence of pname:handleType. |
| -- |
| |
| [open,refpage='VkSemaphoreImportFlags',desc='Bitmask of VkSemaphoreImportFlagBits',type='flags'] |
| -- |
| include::{generated}/api/flags/VkSemaphoreImportFlags.txt[] |
| |
| ifdef::VK_KHR_external_semaphore[] |
| or the equivalent |
| |
| include::{generated}/api/flags/VkSemaphoreImportFlagsKHR.txt[] |
| endif::VK_KHR_external_semaphore[] |
| |
| tname:VkSemaphoreImportFlags is a bitmask type for setting a mask of zero or |
| more elink:VkSemaphoreImportFlagBits. |
| -- |
| endif::VK_KHR_external_semaphore_win32,VK_KHR_external_semaphore_fd,VK_FUCHSIA_external_semaphore[] |
| endif::VK_VERSION_1_1,VK_KHR_external_semaphore[] |
| |
| |
| [[synchronization-events]] |
| == Events |
| |
| [open,refpage='VkEvent',desc='Opaque handle to an event object',type='handles'] |
| -- |
| Events are a synchronization primitive that can: be used to insert a |
| fine-grained dependency between commands submitted to the same queue, or |
| between the host and a queue. |
| Events must: not be used to insert a dependency between commands submitted |
| to different queues. |
| Events have two states - signaled and unsignaled. |
| An application can: signal or unsignal an event either on the host or on the |
| device. |
| A device can: be made to wait for an event to become signaled before |
| executing further operations. |
| No command exists to wait for an event to become signaled on the host, but |
| the current state of an event can: be queried. |
| |
| Events are represented by sname:VkEvent handles: |
| |
| include::{generated}/api/handles/VkEvent.txt[] |
| -- |
| |
| [open,refpage='vkCreateEvent',desc='Create a new event object',type='protos'] |
| -- |
| To create an event, call: |
| |
| include::{generated}/api/protos/vkCreateEvent.txt[] |
| |
| * pname:device is the logical device that creates the event. |
| * pname:pCreateInfo is a pointer to a slink:VkEventCreateInfo structure |
| containing information about how the event is to be created. |
| * pname:pAllocator controls host memory allocation as described in the |
| <<memory-allocation, Memory Allocation>> chapter. |
| * pname:pEvent is a pointer to a handle in which the resulting event |
| object is returned. |
| |
| When created, the event object is in the unsignaled state. |
| |
| ifdef::VK_KHR_portability_subset[] |
| .Valid Usage |
| **** |
| * [[VUID-vkCreateEvent-events-04468]] |
| If the `apiext:VK_KHR_portability_subset` extension is enabled, and |
| slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:events is |
| ename:VK_FALSE, then the implementation does not support |
| <<synchronization-events, events>>, and flink:vkCreateEvent must: not be |
| used |
| **** |
| endif::VK_KHR_portability_subset[] |
| |
| include::{generated}/validity/protos/vkCreateEvent.txt[] |
| -- |
| |
| [open,refpage='VkEventCreateInfo',desc='Structure specifying parameters of a newly created event',type='structs'] |
| -- |
| The sname:VkEventCreateInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkEventCreateInfo.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:flags is a bitmask of elink:VkEventCreateFlagBits defining |
| additional creation parameters. |
| |
| include::{generated}/validity/structs/VkEventCreateInfo.txt[] |
| -- |
| |
| [open,refpage='VkEventCreateFlagBits',desc='Event creation flag bits',type='enums'] |
| -- |
| include::{generated}/api/enums/VkEventCreateFlagBits.txt[] |
| |
| ifndef::VK_KHR_synchronization2[] |
| All values for this enum are defined by extensions. |
| endif::VK_KHR_synchronization2[] |
| ifdef::VK_KHR_synchronization2[] |
| * ename:VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR specifies that host event |
| commands will not be used with this event. |
| endif::VK_KHR_synchronization2[] |
| -- |
| |
| [open,refpage='VkEventCreateFlags',desc='Bitmask of event creation flag bits',type='flags'] |
| -- |
| include::{generated}/api/flags/VkEventCreateFlags.txt[] |
| |
| tname:VkEventCreateFlags is a bitmask type for setting a mask of |
| elink:VkEventCreateFlagBits. |
| -- |
| |
| [open,refpage='vkDestroyEvent',desc='Destroy an event object',type='protos'] |
| -- |
| To destroy an event, call: |
| |
| include::{generated}/api/protos/vkDestroyEvent.txt[] |
| |
| * pname:device is the logical device that destroys the event. |
| * pname:event is the handle of the event to destroy. |
| * pname:pAllocator controls host memory allocation as described in the |
| <<memory-allocation, Memory Allocation>> chapter. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkDestroyEvent-event-01145]] |
| All submitted commands that refer to pname:event must: have completed |
| execution |
| * [[VUID-vkDestroyEvent-event-01146]] |
| If sname:VkAllocationCallbacks were provided when pname:event was |
| created, a compatible set of callbacks must: be provided here |
| * [[VUID-vkDestroyEvent-event-01147]] |
| If no sname:VkAllocationCallbacks were provided when pname:event was |
| created, pname:pAllocator must: be `NULL` |
| **** |
| |
| include::{generated}/validity/protos/vkDestroyEvent.txt[] |
| -- |
| |
| [open,refpage='vkGetEventStatus',desc='Retrieve the status of an event object',type='protos'] |
| -- |
| To query the state of an event from the host, call: |
| |
| include::{generated}/api/protos/vkGetEventStatus.txt[] |
| |
| * pname:device is the logical device that owns the event. |
| * pname:event is the handle of the event to query. |
| |
| Upon success, fname:vkGetEventStatus returns the state of the event object |
| with the following return codes: |
| |
| .Event Object Status Codes |
| [width="80%",options="header"] |
| |==== |
| | Status | Meaning |
| | ename:VK_EVENT_SET | The event specified by pname:event is signaled. |
| | ename:VK_EVENT_RESET | The event specified by pname:event is unsignaled. |
| |==== |
| |
| If a fname:vkCmdSetEvent or fname:vkCmdResetEvent command is in a command |
| buffer that is in the <<commandbuffers-lifecycle, pending state>>, then the |
| value returned by this command may: immediately be out of date. |
| |
| The state of an event can: be updated by the host. |
| The state of the event is immediately changed, and subsequent calls to |
| fname:vkGetEventStatus will return the new state. |
| If an event is already in the requested state, then updating it to the same |
| state has no effect. |
| |
| ifdef::VK_KHR_synchronization2[] |
| .Valid Usage |
| **** |
| * [[VUID-vkGetEventStatus-event-03940]] |
| pname:event must: not have been created with |
| ename:VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR |
| **** |
| endif::VK_KHR_synchronization2[] |
| |
| include::{generated}/validity/protos/vkGetEventStatus.txt[] |
| -- |
| |
| [[synchronization-events-signaling-host]] |
| [open,refpage='vkSetEvent',desc='Set an event to signaled state',type='protos'] |
| -- |
| To set the state of an event to signaled from the host, call: |
| |
| include::{generated}/api/protos/vkSetEvent.txt[] |
| |
| * pname:device is the logical device that owns the event. |
| * pname:event is the event to set. |
| |
| When flink:vkSetEvent is executed on the host, it defines an _event signal |
| operation_ which sets the event to the signaled state. |
| |
| If pname:event is already in the signaled state when flink:vkSetEvent is |
| executed, then flink:vkSetEvent has no effect, and no event signal operation |
| occurs. |
| |
| ifdef::VK_KHR_synchronization2[] |
| .Valid Usage |
| **** |
| * [[VUID-vkSetEvent-event-03941]] |
| pname:event must: not have been created with |
| ename:VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR |
| **** |
| endif::VK_KHR_synchronization2[] |
| |
| include::{generated}/validity/protos/vkSetEvent.txt[] |
| -- |
| |
| [[synchronization-events-unsignaling-host]] |
| [open,refpage='vkResetEvent',desc='Reset an event to non-signaled state',type='protos'] |
| -- |
| To set the state of an event to unsignaled from the host, call: |
| |
| include::{generated}/api/protos/vkResetEvent.txt[] |
| |
| * pname:device is the logical device that owns the event. |
| * pname:event is the event to reset. |
| |
| When flink:vkResetEvent is executed on the host, it defines an _event |
| unsignal operation_ which resets the event to the unsignaled state. |
| |
| If pname:event is already in the unsignaled state when flink:vkResetEvent is |
| executed, then flink:vkResetEvent has no effect, and no event unsignal |
| operation occurs. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkResetEvent-event-03821]] |
| There must: be an execution dependency between fname:vkResetEvent and |
| the execution of any flink:vkCmdWaitEvents that includes pname:event in |
| its pname:pEvents parameter |
| ifdef::VK_KHR_synchronization2[] |
| * [[VUID-vkResetEvent-event-03822]] |
| There must: be an execution dependency between fname:vkResetEvent and |
| the execution of any flink:vkCmdWaitEvents2KHR that includes pname:event |
| in its pname:pEvents parameter |
| endif::VK_KHR_synchronization2[] |
| ifdef::VK_KHR_synchronization2[] |
| * [[VUID-vkResetEvent-event-03823]] |
| pname:event must: not have been created with |
| ename:VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR |
| endif::VK_KHR_synchronization2[] |
| **** |
| |
| include::{generated}/validity/protos/vkResetEvent.txt[] |
| -- |
| |
| The state of an event can: also be updated on the device by commands |
| inserted in command buffers. |
| |
| [[synchronization-events-signaling-device]] |
| ifdef::VK_KHR_synchronization2[] |
| [open,refpage='vkCmdSetEvent2KHR',desc='Set an event object to signaled state',type='protos'] |
| -- |
| To signal an event from a device, call: |
| |
| include::{generated}/api/protos/vkCmdSetEvent2KHR.txt[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:event is the event that will be signaled. |
| * pname:pDependencyInfo is a pointer to a slink:VkDependencyInfoKHR |
| structure defining the first scopes of this operation. |
| |
| When flink:vkCmdSetEvent2KHR is submitted to a queue, it defines the first |
| half of memory dependencies defined by pname:pDependencyInfo, as well as an |
| event signal operation which sets the event to the signaled state. |
| A memory dependency is defined between the event signal operation and |
| commands that occur earlier in submission order. |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> and |
| <<synchronization-dependencies-access-scopes, access scope>> are defined by |
| the union of all the memory dependencies defined by pname:pDependencyInfo, |
| and are applied to all operations that occur earlier in |
| <<synchronization-submission-order,submission order>>. |
| <<synchronization-queue-transfers, Queue family ownership transfers>> and |
| <<synchronization-image-layout-transitions, image layout transitions>> |
| defined by pname:pDependencyInfo are also included in the first scopes. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| includes only the event signal operation, and any |
| <<synchronization-queue-transfers, queue family ownership transfers>> and |
| <<synchronization-image-layout-transitions, image layout transitions>> |
| defined by pname:pDependencyInfo. |
| |
| The second <<synchronization-dependencies-access-scopes, access scope>> |
| includes only <<synchronization-queue-transfers, queue family ownership |
| transfers>> and <<synchronization-image-layout-transitions, image layout |
| transitions>>. |
| |
| Future flink:vkCmdWaitEvents2KHR commands rely on all values of each element |
| in pname:pDependencyInfo matching exactly with those used to signal the |
| corresponding event. |
| flink:vkCmdWaitEvents must: not be used to wait on the result of a signal |
| operation defined by fname:vkCmdSetEvent2KHR. |
| |
| [NOTE] |
| .Note |
| ==== |
| The extra information provided by flink:vkCmdSetEvent2KHR compared to |
| flink:vkCmdSetEvent allows implementations to more efficiently schedule the |
| operations required to satisfy the requested dependencies. |
| With flink:vkCmdSetEvent, the full dependency information is not known until |
| flink:vkCmdWaitEvents is recorded, forcing implementations to insert the |
| required operations at that point and not before. |
| ==== |
| |
| If pname:event is already in the signaled state when flink:vkCmdSetEvent2KHR |
| is executed on the device, then flink:vkCmdSetEvent2KHR has no effect, no |
| event signal operation occurs, and no dependency is generated. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdSetEvent2KHR-synchronization2-03824]] |
| The <<features-synchronization2, pname:synchronization2>> feature must: |
| be enabled |
| * [[VUID-vkCmdSetEvent2KHR-dependencyFlags-03825]] |
| The pname:dependencyFlags member of pname:pDependencyInfo must: be `0` |
| ifdef::VK_VERSION_1_1,VK_KHR_device_group[] |
| * [[VUID-vkCmdSetEvent2KHR-commandBuffer-03826]] |
| The current device mask of pname:commandBuffer must: include exactly one |
| physical device |
| endif::VK_VERSION_1_1,VK_KHR_device_group[] |
| * [[VUID-vkCmdSetEvent2KHR-srcStageMask-03827]] |
| The pname:srcStageMask member of any element of the |
| pname:pMemoryBarriers, pname:pBufferMemoryBarriers, or |
| pname:pImageMemoryBarriers members of pname:pDependencyInfo must: only |
| include pipeline stages valid for the queue family that was used to |
| create the command pool that pname:commandBuffer was allocated from |
| * [[VUID-vkCmdSetEvent2KHR-dstStageMask-03828]] |
| The pname:dstStageMask member of any element of the |
| pname:pMemoryBarriers, pname:pBufferMemoryBarriers, or |
| pname:pImageMemoryBarriers members of pname:pDependencyInfo must: only |
| include pipeline stages valid for the queue family that was used to |
| create the command pool that pname:commandBuffer was allocated from |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetEvent2KHR.txt[] |
| -- |
| |
| [open,refpage='VkDependencyInfoKHR',desc='Structure specifying dependency information for a synchronization command',type='structs'] |
| -- |
| The sname:VkDependencyInfoKHR structure is defined as: |
| |
| include::{generated}/api/structs/VkDependencyInfoKHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:dependencyFlags is a bitmask of elink:VkDependencyFlagBits |
| specifying how execution and memory dependencies are formed. |
| * pname:memoryBarrierCount is the length of the pname:pMemoryBarriers |
| array. |
| * pname:pMemoryBarriers is a pointer to an array of |
| slink:VkMemoryBarrier2KHR structures that define memory dependencies |
| between any memory accesses. |
| * pname:bufferMemoryBarrierCount is the length of the |
| pname:pBufferMemoryBarriers array. |
| * pname:pBufferMemoryBarriers is a pointer to an array of |
| slink:VkBufferMemoryBarrier2KHR structures that define memory |
| dependencies between buffer ranges. |
| * pname:imageMemoryBarrierCount is the length of the |
| pname:pImageMemoryBarriers array. |
| * pname:pImageMemoryBarriers is a pointer to an array of |
| slink:VkImageMemoryBarrier2KHR structures that define memory |
| dependencies between image subresources. |
| |
| This structure defines a set of <<synchronization-dependencies-memory, |
| memory dependencies>>, as well as <<synchronization-queue-transfers, queue |
| family transfer operations>> and <<synchronization-image-layout-transitions, |
| image layout transitions>>. |
| |
| Each member of pname:pMemoryBarriers, pname:pBufferMemoryBarriers, and |
| pname:pImageMemoryBarriers defines a separate |
| <<synchronization-dependencies-memory, memory dependency>>. |
| |
| include::{generated}/validity/structs/VkDependencyInfoKHR.txt[] |
| -- |
| endif::VK_KHR_synchronization2[] |
| |
| [open,refpage='vkCmdSetEvent',desc='Set an event object to signaled state',type='protos'] |
| -- |
| :refpage: vkCmdSetEvent |
| |
| To set the state of an event to signaled from a device, call: |
| |
| include::{generated}/api/protos/vkCmdSetEvent.txt[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:event is the event that will be signaled. |
| * pname:stageMask specifies the <<synchronization-pipeline-stages,source |
| stage mask>> used to determine the first |
| <<synchronization-dependencies-scopes, synchronization scope>>. |
| |
| |
| ifdef::VK_KHR_synchronization2[] |
| fname:vkCmdSetEvent behaves identically to flink:vkCmdSetEvent2KHR, except |
| that it does not define an access scope, and must: only be used with |
| flink:vkCmdWaitEvents, not flink:vkCmdWaitEvents2KHR. |
| endif::VK_KHR_synchronization2[] |
| |
| ifndef::VK_KHR_synchronization2[] |
| When flink:vkCmdSetEvent is submitted to a queue, it defines an execution |
| dependency on commands that were submitted before it, and defines an event |
| signal operation which sets the event to the signaled state. |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> |
| includes all commands that occur earlier in |
| <<synchronization-submission-order,submission order>>. |
| The synchronization scope is limited to operations on the pipeline stages |
| determined by the <<synchronization-pipeline-stages-masks, source stage |
| mask>> specified by pname:stageMask. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| includes only the event signal operation. |
| |
| If pname:event is already in the signaled state when flink:vkCmdSetEvent is |
| executed on the device, then flink:vkCmdSetEvent has no effect, no event |
| signal operation occurs, and no execution dependency is generated. |
| endif::VK_KHR_synchronization2[] |
| |
| .Valid Usage |
| **** |
| :stageMaskName: stageMask |
| include::{chapters}/commonvalidity/stage_mask_common.txt[] |
| * [[VUID-vkCmdSetEvent-stageMask-01149]] |
| pname:stageMask must: not include ename:VK_PIPELINE_STAGE_HOST_BIT |
| ifdef::VK_VERSION_1_1,VK_KHR_device_group[] |
| * [[VUID-vkCmdSetEvent-commandBuffer-01152]] |
| pname:commandBuffer's current device mask must: include exactly one |
| physical device |
| endif::VK_VERSION_1_1,VK_KHR_device_group[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetEvent.txt[] |
| -- |
| |
| [[synchronization-events-unsignaling-device]] |
| ifdef::VK_KHR_synchronization2[] |
| [open,refpage='vkCmdResetEvent2KHR',desc='Reset an event object to non-signaled state',type='protos'] |
| -- |
| :refpage: vkCmdResetEvent2KHR |
| |
| To unsignal the event from a device, call: |
| |
| include::{generated}/api/protos/vkCmdResetEvent2KHR.txt[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:event is the event that will be unsignaled. |
| * pname:stageMask is a tlink:VkPipelineStageFlags2KHR mask of pipeline |
| stages used to determine the first |
| <<synchronization-dependencies-scopes, synchronization scope>>. |
| |
| When flink:vkCmdResetEvent2KHR is submitted to a queue, it defines an |
| execution dependency on commands that were submitted before it, and defines |
| an event unsignal operation which resets the event to the unsignaled state. |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> |
| includes all commands that occur earlier in |
| <<synchronization-submission-order,submission order>>. |
| The synchronization scope is limited to operations by pname:stageMask or |
| stages that are <<synchronization-pipeline-stages-order,logically earlier>> |
| than pname:stageMask. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| includes only the event unsignal operation. |
| |
| If pname:event is already in the unsignaled state when |
| flink:vkCmdResetEvent2KHR is executed on the device, then this command has |
| no effect, no event unsignal operation occurs, and no execution dependency |
| is generated. |
| |
| .Valid Usage |
| **** |
| :stageMaskName: stageMask |
| include::{chapters}/commonvalidity/stage_mask_2_common.txt[] |
| * [[VUID-vkCmdResetEvent2KHR-synchronization2-03829]] |
| The <<features-synchronization2, pname:synchronization2>> feature must: |
| be enabled |
| * [[VUID-vkCmdResetEvent2KHR-stageMask-03830]] |
| pname:stageMask must: not include ename:VK_PIPELINE_STAGE_2_HOST_BIT_KHR |
| * [[VUID-vkCmdResetEvent2KHR-event-03831]] |
| There must: be an execution dependency between fname:vkCmdResetEvent2KHR |
| and the execution of any flink:vkCmdWaitEvents that includes pname:event |
| in its pname:pEvents parameter |
| * [[VUID-vkCmdResetEvent2KHR-event-03832]] |
| There must: be an execution dependency between fname:vkCmdResetEvent2KHR |
| and the execution of any flink:vkCmdWaitEvents2KHR that includes |
| pname:event in its pname:pEvents parameter |
| ifdef::VK_VERSION_1_1,VK_KHR_device_group[] |
| * [[VUID-vkCmdResetEvent2KHR-commandBuffer-03833]] |
| pname:commandBuffer's current device mask must: include exactly one |
| physical device |
| endif::VK_VERSION_1_1,VK_KHR_device_group[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdResetEvent2KHR.txt[] |
| -- |
| endif::VK_KHR_synchronization2[] |
| |
| [open,refpage='vkCmdResetEvent',desc='Reset an event object to non-signaled state',type='protos'] |
| -- |
| :refpage: vkCmdResetEvent |
| |
| To set the state of an event to unsignaled from a device, call: |
| |
| include::{generated}/api/protos/vkCmdResetEvent.txt[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:event is the event that will be unsignaled. |
| * pname:stageMask is a bitmask of elink:VkPipelineStageFlagBits specifying |
| the <<synchronization-pipeline-stages, source stage mask>> used to |
| determine when the pname:event is unsignaled. |
| |
| ifdef::VK_KHR_synchronization2[] |
| fname:vkCmdResetEvent behaves identically to flink:vkCmdResetEvent2KHR. |
| endif::VK_KHR_synchronization2[] |
| |
| ifndef::VK_KHR_synchronization2[] |
| When flink:vkCmdResetEvent is submitted to a queue, it defines an execution |
| dependency on commands that were submitted before it, and defines an event |
| unsignal operation which resets the event to the unsignaled state. |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> |
| includes all commands that occur earlier in |
| <<synchronization-submission-order,submission order>>. |
| The synchronization scope is limited to operations on the pipeline stages |
| determined by the <<synchronization-pipeline-stages-masks, source stage |
| mask>> specified by pname:stageMask. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| includes only the event unsignal operation. |
| |
| If pname:event is already in the unsignaled state when flink:vkCmdResetEvent |
| is executed on the device, then flink:vkCmdResetEvent has no effect, no |
| event unsignal operation occurs, and no execution dependency is generated. |
| endif::VK_KHR_synchronization2[] |
| |
| .Valid Usage |
| **** |
| :stageMaskName: stageMask |
| include::{chapters}/commonvalidity/stage_mask_common.txt[] |
| * [[VUID-vkCmdResetEvent-stageMask-01153]] |
| pname:stageMask must: not include ename:VK_PIPELINE_STAGE_HOST_BIT |
| * [[VUID-vkCmdResetEvent-event-03834]] |
| There must: be an execution dependency between fname:vkCmdResetEvent and |
| the execution of any flink:vkCmdWaitEvents that includes pname:event in |
| its pname:pEvents parameter |
| ifdef::VK_KHR_synchronization2[] |
| * [[VUID-vkCmdResetEvent-event-03835]] |
| There must: be an execution dependency between fname:vkCmdResetEvent and |
| the execution of any flink:vkCmdWaitEvents2KHR that includes pname:event |
| in its pname:pEvents parameter |
| endif::VK_KHR_synchronization2[] |
| ifdef::VK_VERSION_1_1,VK_KHR_device_group[] |
| * [[VUID-vkCmdResetEvent-commandBuffer-01157]] |
| pname:commandBuffer's current device mask must: include exactly one |
| physical device |
| endif::VK_VERSION_1_1,VK_KHR_device_group[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdResetEvent.txt[] |
| -- |
| |
| ifdef::VK_KHR_synchronization2[] |
| [open,refpage='vkCmdWaitEvents2KHR',desc='Wait for one or more events',type='protos'] |
| -- |
| To wait for one or more events to enter the signaled state on a device, |
| call: |
| |
| [[synchronization-events-waiting-device]] |
| include::{generated}/api/protos/vkCmdWaitEvents2KHR.txt[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:eventCount is the length of the pname:pEvents array. |
| * pname:pEvents is a pointer to an array of pname:eventCount events to |
| wait on. |
| * pname:pDependencyInfos is a pointer to an array of pname:eventCount |
| slink:VkDependencyInfoKHR structures, defining the second |
| <<synchronization-dependencies-scopes, synchronization scope>>. |
| |
| When fname:vkCmdWaitEvents2KHR is submitted to a queue, it inserts memory |
| dependencies according to the elements of pname:pDependencyInfos and each |
| corresponding element of pname:pEvents. |
| fname:vkCmdWaitEvents2KHR must: not be used to wait on event signal |
| operations occurring on other queues, or signal operations execyted by |
| flink:vkCmdSetEvent. |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> and |
| <<synchronization-dependencies-access-scopes, access scope>> of each memory |
| dependency defined by any element [eq]#i# of pname:pDependencyInfos are |
| applied to operations that occurred earlier in |
| <<synchronization-submission-order,submission order>> than the last event |
| signal operation on element [eq]#i# of pname:pEvents. |
| |
| Signal operations for an event at index [eq]#i# are only included if: |
| |
| * The event was signaled by a flink:vkCmdSetEvent2KHR command that |
| occurred earlier in <<synchronization-submission-order,submission |
| order>> with a pname:dependencyInfo parameter exactly equal to the |
| element of pname:pDependencyInfos at index [eq]#i# ; or |
| * The event was created without ename:VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR, |
| and the first <<synchronization-dependencies-scopes, synchronization |
| scope>> defined by the element of pname:pDependencyInfos at index |
| [eq]#i# only includes host operations |
| (ename:VK_PIPELINE_STAGE_2_HOST_BIT_KHR). |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| and <<synchronization-dependencies-access-scopes, access scope>> of each |
| memory dependency defined by any element [eq]#i# of pname:pDependencyInfos |
| are applied to operations that occurred later in |
| <<synchronization-submission-order,submission order>> than |
| fname:vkCmdWaitEvents2KHR. |
| |
| [NOTE] |
| .Note |
| ==== |
| flink:vkCmdWaitEvents2KHR is used with flink:vkCmdSetEvent2KHR to define a |
| memory dependency between two sets of action commands, roughly in the same |
| way as pipeline barriers, but split into two commands such that work between |
| the two may: execute unhindered. |
| ==== |
| |
| [NOTE] |
| .Note |
| ==== |
| Applications should be careful to avoid race conditions when using events. |
| There is no direct ordering guarantee between fname:vkCmdSetEvent2KHR and |
| flink:vkCmdResetEvent2KHR, flink:vkCmdResetEvent, or flink:vkCmdSetEvent. |
| Another execution dependency (e.g. a pipeline barrier or semaphore with |
| ename:VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR) is needed to prevent such a |
| race condition. |
| ==== |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdWaitEvents2KHR-synchronization2-03836]] |
| The <<features-synchronization2, pname:synchronization2>> feature must: |
| be enabled |
| * [[VUID-vkCmdWaitEvents2KHR-pEvents-03837]] |
| Members of pname:pEvents must: not have been signaled by |
| flink:vkCmdSetEvent |
| * [[VUID-vkCmdWaitEvents2KHR-pEvents-03838]] |
| For any element [eq]#i# of pname:pEvents, if that event is signaled by |
| flink:vkCmdSetEvent2KHR, that command's pname:dependencyInfo parameter |
| must: be exactly equal to the [eq]##i##th element of |
| pname:pDependencyInfos |
| * [[VUID-vkCmdWaitEvents2KHR-pEvents-03839]] |
| For any element [eq]#i# of pname:pEvents, if that event is signaled by |
| flink:vkSetEvent, barriers in the [eq]##i##th element of |
| pname:pDependencyInfos must: include only host operations in their first |
| <<synchronization-dependencies-scopes, synchronization scope>> |
| * [[VUID-vkCmdWaitEvents2KHR-pEvents-03840]] |
| For any element [eq]#i# of pname:pEvents, if barriers in the [eq]##i##th |
| element of pname:pDependencyInfos include only host operations, the |
| [eq]##i##th element of pname:pEvents must: be signaled before |
| flink:vkCmdWaitEvents2KHR is executed |
| * [[VUID-vkCmdWaitEvents2KHR-pEvents-03841]] |
| For any element [eq]#i# of pname:pEvents, if barriers in the [eq]##i##th |
| element of pname:pDependencyInfos do not include host operations, the |
| [eq]##i##th element of pname:pEvents must: be signaled by a |
| corresponding flink:vkCmdSetEvent2KHR that occurred earlier in |
| <<synchronization-submission-order,submission order>> |
| * [[VUID-vkCmdWaitEvents2KHR-srcStageMask-03842]] |
| The pname:srcStageMask member of any element of the |
| pname:pMemoryBarriers, pname:pBufferMemoryBarriers, or |
| pname:pImageMemoryBarriers members of pname:pDependencyInfos must: |
| either include only pipeline stages valid for the queue family that was |
| used to create the command pool that pname:commandBuffer was allocated |
| from, or include only ename:VK_PIPELINE_STAGE_2_HOST_BIT_KHR |
| * [[VUID-vkCmdWaitEvents2KHR-dstStageMask-03843]] |
| The pname:dstStageMask member of any element of the |
| pname:pMemoryBarriers, pname:pBufferMemoryBarriers, or |
| pname:pImageMemoryBarriers members of pname:pDependencyInfos must: only |
| include pipeline stages valid for the queue family that was used to |
| create the command pool that pname:commandBuffer was allocated from |
| * [[VUID-vkCmdWaitEvents2KHR-dependencyFlags-03844]] |
| The pname:dependencyFlags member of any element of pname:pDependencyInfo |
| must: be `0` |
| * [[VUID-vkCmdWaitEvents2KHR-pEvents-03845]] |
| If pname:pEvents includes one or more events that will be signaled by |
| flink:vkSetEvent after pname:commandBuffer has been submitted to a |
| queue, then fname:vkCmdWaitEvents2KHR must: not be called inside a |
| render pass instance |
| * [[VUID-vkCmdWaitEvents2KHR-commandBuffer-03846]] |
| pname:commandBuffer's current device mask must: include exactly one |
| physical device |
| **** |
| |
| include::{generated}/validity/protos/vkCmdWaitEvents2KHR.txt[] |
| -- |
| endif::VK_KHR_synchronization2[] |
| |
| [open,refpage='vkCmdWaitEvents',desc='Wait for one or more events and insert a set of memory',type='protos'] |
| -- |
| :refpage: vkCmdWaitEvents |
| |
| To wait for one or more events to enter the signaled state on a device, |
| call: |
| |
| [[synchronization-events-waiting-device]] |
| include::{generated}/api/protos/vkCmdWaitEvents.txt[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:eventCount is the length of the pname:pEvents array. |
| * pname:pEvents is a pointer to an array of event object handles to wait |
| on. |
| * pname:srcStageMask is a bitmask of elink:VkPipelineStageFlagBits |
| specifying the <<synchronization-pipeline-stages, source stage mask>>. |
| * pname:dstStageMask is a bitmask of elink:VkPipelineStageFlagBits |
| specifying the <<synchronization-pipeline-stages, destination stage |
| mask>>. |
| * pname:memoryBarrierCount is the length of the pname:pMemoryBarriers |
| array. |
| * pname:pMemoryBarriers is a pointer to an array of slink:VkMemoryBarrier |
| structures. |
| * pname:bufferMemoryBarrierCount is the length of the |
| pname:pBufferMemoryBarriers array. |
| * pname:pBufferMemoryBarriers is a pointer to an array of |
| slink:VkBufferMemoryBarrier structures. |
| * pname:imageMemoryBarrierCount is the length of the |
| pname:pImageMemoryBarriers array. |
| * pname:pImageMemoryBarriers is a pointer to an array of |
| slink:VkImageMemoryBarrier structures. |
| |
| ifdef::VK_KHR_synchronization2[] |
| fname:vkCmdWaitEvents is largely similar to flink:vkCmdWaitEvents2KHR, but |
| can: only wait on signal operations defined by flink:vkCmdSetEvent. |
| As flink:vkCmdSetEvent does not define any access scopes, |
| fname:vkCmdWaitEvents defines the first access scope for each event signal |
| operation in addition to its own access scopes. |
| |
| [NOTE] |
| .Note |
| ==== |
| Since flink:vkCmdSetEvent does not have any dependency information beyond a |
| stage mask, implementations do not have the same opportunity to perform |
| <<synchronization-dependencies-available-and-visible, availability and |
| visibility operations>> or <<synchronization-image-layout-transitions, image |
| layout transitions>> in advance as they do with flink:vkCmdSetEvent2KHR and |
| flink:vkCmdWaitEvents2KHR. |
| ==== |
| endif::VK_KHR_synchronization2[] |
| |
| When fname:vkCmdWaitEvents is submitted to a queue, it defines a memory |
| dependency between prior event signal operations on the same queue or the |
| host, and subsequent commands. |
| fname:vkCmdWaitEvents must: not be used to wait on event signal operations |
| occurring on other queues. |
| |
| The first synchronization scope only includes event signal operations that |
| operate on members of pname:pEvents, and the operations that happened-before |
| the event signal operations. |
| Event signal operations performed by flink:vkCmdSetEvent that occur earlier |
| in <<synchronization-submission-order,submission order>> are included in the |
| first synchronization scope, if the <<synchronization-pipeline-stages-order, |
| logically latest>> pipeline stage in their pname:stageMask parameter is |
| <<synchronization-pipeline-stages-order, logically earlier>> than or equal |
| to the <<synchronization-pipeline-stages-order, logically latest>> pipeline |
| stage in pname:srcStageMask. |
| Event signal operations performed by flink:vkSetEvent are only included in |
| the first synchronization scope if ename:VK_PIPELINE_STAGE_HOST_BIT is |
| included in pname:srcStageMask. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| includes all commands that occur later in |
| <<synchronization-submission-order,submission order>>. |
| The second synchronization scope is limited to operations on the pipeline |
| stages determined by the <<synchronization-pipeline-stages-masks, |
| destination stage mask>> specified by pname:dstStageMask. |
| |
| The first <<synchronization-dependencies-access-scopes, access scope>> is |
| limited to accesses in the pipeline stages determined by the |
| <<synchronization-pipeline-stages-masks, source stage mask>> specified by |
| pname:srcStageMask. |
| Within that, the first access scope only includes the first access scopes |
| defined by elements of the pname:pMemoryBarriers, |
| pname:pBufferMemoryBarriers and pname:pImageMemoryBarriers arrays, which |
| each define a set of <<synchronization-memory-barriers, memory barriers>>. |
| If no memory barriers are specified, then the first access scope includes no |
| accesses. |
| |
| The second <<synchronization-dependencies-access-scopes, access scope>> is |
| limited to accesses in the pipeline stages determined by the |
| <<synchronization-pipeline-stages-masks, destination stage mask>> specified |
| by pname:dstStageMask. |
| Within that, the second access scope only includes the second access scopes |
| defined by elements of the pname:pMemoryBarriers, |
| pname:pBufferMemoryBarriers and pname:pImageMemoryBarriers arrays, which |
| each define a set of <<synchronization-memory-barriers, memory barriers>>. |
| If no memory barriers are specified, then the second access scope includes |
| no accesses. |
| |
| ifndef::VK_KHR_synchronization2[] |
| [NOTE] |
| .Note |
| ==== |
| flink:vkCmdWaitEvents is used with flink:vkCmdSetEvent to define a memory |
| dependency between two sets of action commands, roughly in the same way as |
| pipeline barriers, but split into two commands such that work between the |
| two may: execute unhindered. |
| |
| Unlike flink:vkCmdPipelineBarrier, a <<synchronization-queue-transfers, |
| queue family ownership transfer>> cannot: be performed using |
| flink:vkCmdWaitEvents. |
| ==== |
| |
| [NOTE] |
| .Note |
| ==== |
| Applications should be careful to avoid race conditions when using events. |
| There is no direct ordering guarantee between flink:vkCmdWaitEvents and |
| ifdef::VK_KHR_synchronization2[flink:vkCmdResetEvent2KHR,] |
| flink:vkCmdResetEvent, or flink:vkCmdSetEvent. |
| Another execution dependency (e.g. a pipeline barrier or semaphore with |
| ename:VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) is needed to prevent such a race |
| condition. |
| ==== |
| endif::VK_KHR_synchronization2[] |
| |
| .Valid Usage |
| **** |
| :stageMaskName: srcStageMask |
| include::{chapters}/commonvalidity/stage_mask_common.txt[] |
| |
| :stageMaskName: dstStageMask |
| include::{chapters}/commonvalidity/stage_mask_common.txt[] |
| include::{chapters}/commonvalidity/fine_sync_commands_common.txt[] |
| * [[VUID-vkCmdWaitEvents-srcStageMask-01158]] |
| pname:srcStageMask must: be the bitwise OR of the pname:stageMask |
| parameter used in previous calls to fname:vkCmdSetEvent with any of the |
| elements of pname:pEvents and ename:VK_PIPELINE_STAGE_HOST_BIT if any of |
| the elements of pname:pEvents was set using fname:vkSetEvent |
| * [[VUID-vkCmdWaitEvents-pEvents-01163]] |
| If pname:pEvents includes one or more events that will be signaled by |
| fname:vkSetEvent after pname:commandBuffer has been submitted to a |
| queue, then fname:vkCmdWaitEvents must: not be called inside a render |
| pass instance |
| * [[VUID-vkCmdWaitEvents-srcQueueFamilyIndex-02803]] |
| The pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex members of |
| any element of pname:pBufferMemoryBarriers or pname:pImageMemoryBarriers |
| must: be equal |
| ifdef::VK_VERSION_1_1,VK_KHR_device_group[] |
| * [[VUID-vkCmdWaitEvents-commandBuffer-01167]] |
| pname:commandBuffer's current device mask must: include exactly one |
| physical device |
| endif::VK_VERSION_1_1,VK_KHR_device_group[] |
| ifdef::VK_KHR_synchronization2[] |
| * [[VUID-vkCmdWaitEvents-pEvents-03847]] |
| Elements of pname:pEvents must: not have been signaled by |
| flink:vkCmdSetEvent2KHR |
| endif::VK_KHR_synchronization2[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdWaitEvents.txt[] |
| -- |
| |
| |
| [[synchronization-pipeline-barriers]] |
| == Pipeline Barriers |
| |
| ifdef::VK_KHR_synchronization2[] |
| [open,refpage='vkCmdPipelineBarrier2KHR',desc='Insert a memory dependency',type='protos'] |
| -- |
| :refpage: vkCmdPipelineBarrier2KHR |
| |
| To record a pipeline barrier, call: |
| |
| include::{generated}/api/protos/vkCmdPipelineBarrier2KHR.txt[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:pDependencyInfo is a pointer to a slink:VkDependencyInfoKHR |
| structure defining the scopes of this operation. |
| |
| When flink:vkCmdPipelineBarrier2KHR is submitted to a queue, it defines |
| memory dependencies between commands that were submitted before it, and |
| those submitted after it. |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> and |
| <<synchronization-dependencies-access-scopes, access scope>> of each memory |
| dependency defined by any element [eq]#i# of pname:pDependencyInfos are |
| applied to operations that occurred earlier in |
| <<synchronization-submission-order,submission order>>. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| and <<synchronization-dependencies-access-scopes, access scope>> of each |
| memory dependency defined by any element [eq]#i# of pname:pDependencyInfos |
| are applied to operations that occurred later in |
| <<synchronization-submission-order,submission order>>. |
| |
| If fname:vkCmdPipelineBarrier2KHR is recorded within a render pass instance, |
| the synchronization scopes are |
| <<synchronization-pipeline-barriers-subpass-self-dependencies, limited to |
| operations within the same subpass>>. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/pipeline_barrier_common.txt[] |
| * [[VUID-vkCmdPipelineBarrier2KHR-synchronization2-03848]] |
| The <<features-synchronization2, pname:synchronization2>> feature must: |
| be enabled |
| * [[VUID-vkCmdPipelineBarrier2KHR-srcStageMask-03849]] |
| The pname:srcStageMask member of any element of the |
| pname:pMemoryBarriers, pname:pBufferMemoryBarriers, or |
| pname:pImageMemoryBarriers members of pname:pDependencyInfo must: only |
| include pipeline stages valid for the queue family that was used to |
| create the command pool that pname:commandBuffer was allocated from |
| * [[VUID-vkCmdPipelineBarrier2KHR-dstStageMask-03850]] |
| The pname:dstStageMask member of any element of the |
| pname:pMemoryBarriers, pname:pBufferMemoryBarriers, or |
| pname:pImageMemoryBarriers members of pname:pDependencyInfo must: only |
| include pipeline stages valid for the queue family that was used to |
| create the command pool that pname:commandBuffer was allocated from |
| **** |
| |
| include::{generated}/validity/protos/vkCmdPipelineBarrier2KHR.txt[] |
| -- |
| endif::VK_KHR_synchronization2[] |
| |
| [open,refpage='vkCmdPipelineBarrier',desc='Insert a memory dependency',type='protos'] |
| -- |
| :refpage: vkCmdPipelineBarrier |
| |
| To record a pipeline barrier, call: |
| |
| include::{generated}/api/protos/vkCmdPipelineBarrier.txt[] |
| |
| * pname:commandBuffer is the command buffer into which the command is |
| recorded. |
| * pname:srcStageMask is a bitmask of elink:VkPipelineStageFlagBits |
| specifying the <<synchronization-pipeline-stages-masks,source stages>>. |
| * pname:dstStageMask is a bitmask of elink:VkPipelineStageFlagBits |
| specifying the <<synchronization-pipeline-stages-masks,destination |
| stages>>. |
| * pname:dependencyFlags is a bitmask of elink:VkDependencyFlagBits |
| specifying how execution and memory dependencies are formed. |
| * pname:memoryBarrierCount is the length of the pname:pMemoryBarriers |
| array. |
| * pname:pMemoryBarriers is a pointer to an array of slink:VkMemoryBarrier |
| structures. |
| * pname:bufferMemoryBarrierCount is the length of the |
| pname:pBufferMemoryBarriers array. |
| * pname:pBufferMemoryBarriers is a pointer to an array of |
| slink:VkBufferMemoryBarrier structures. |
| * pname:imageMemoryBarrierCount is the length of the |
| pname:pImageMemoryBarriers array. |
| * pname:pImageMemoryBarriers is a pointer to an array of |
| slink:VkImageMemoryBarrier structures. |
| |
| ifdef::VK_KHR_synchronization2[] |
| fname:vkCmdPipelineBarrier operates almost identically to |
| flink:vkCmdPipelineBarrier2KHR, except that the scopes and barriers are |
| defined as direct parameters rather than being defined by an |
| slink:VkDependencyInfoKHR. |
| endif::VK_KHR_synchronization2[] |
| |
| When flink:vkCmdPipelineBarrier is submitted to a queue, it defines a memory |
| dependency between commands that were submitted before it, and those |
| submitted after it. |
| |
| If flink:vkCmdPipelineBarrier was recorded outside a render pass instance, |
| the first <<synchronization-dependencies-scopes, synchronization scope>> |
| includes all commands that occur earlier in |
| <<synchronization-submission-order,submission order>>. |
| If flink:vkCmdPipelineBarrier was recorded inside a render pass instance, |
| the first synchronization scope includes only commands that occur earlier in |
| <<synchronization-submission-order,submission order>> within the same |
| subpass. |
| In either case, the first synchronization scope is limited to operations on |
| the pipeline stages determined by the |
| <<synchronization-pipeline-stages-masks, source stage mask>> specified by |
| pname:srcStageMask. |
| |
| If flink:vkCmdPipelineBarrier was recorded outside a render pass instance, |
| the second <<synchronization-dependencies-scopes, synchronization scope>> |
| includes all commands that occur later in |
| <<synchronization-submission-order,submission order>>. |
| If flink:vkCmdPipelineBarrier was recorded inside a render pass instance, |
| the second synchronization scope includes only commands that occur later in |
| <<synchronization-submission-order,submission order>> within the same |
| subpass. |
| In either case, the second synchronization scope is limited to operations on |
| the pipeline stages determined by the |
| <<synchronization-pipeline-stages-masks, destination stage mask>> specified |
| by pname:dstStageMask. |
| |
| The first <<synchronization-dependencies-access-scopes, access scope>> is |
| limited to accesses in the pipeline stages determined by the |
| <<synchronization-pipeline-stages-masks, source stage mask>> specified by |
| pname:srcStageMask. |
| Within that, the first access scope only includes the first access scopes |
| defined by elements of the pname:pMemoryBarriers, |
| pname:pBufferMemoryBarriers and pname:pImageMemoryBarriers arrays, which |
| each define a set of <<synchronization-memory-barriers, memory barriers>>. |
| If no memory barriers are specified, then the first access scope includes no |
| accesses. |
| |
| The second <<synchronization-dependencies-access-scopes, access scope>> is |
| limited to accesses in the pipeline stages determined by the |
| <<synchronization-pipeline-stages-masks, destination stage mask>> specified |
| by pname:dstStageMask. |
| Within that, the second access scope only includes the second access scopes |
| defined by elements of the pname:pMemoryBarriers, |
| pname:pBufferMemoryBarriers and pname:pImageMemoryBarriers arrays, which |
| each define a set of <<synchronization-memory-barriers, memory barriers>>. |
| If no memory barriers are specified, then the second access scope includes |
| no accesses. |
| |
| If pname:dependencyFlags includes ename:VK_DEPENDENCY_BY_REGION_BIT, then |
| any dependency between <<synchronization-framebuffer-regions, |
| framebuffer-space>> pipeline stages is |
| <<synchronization-framebuffer-regions, framebuffer-local>> - otherwise it is |
| <<synchronization-framebuffer-regions, framebuffer-global>>. |
| |
| .Valid Usage |
| **** |
| :stageMaskName: srcStageMask |
| include::{chapters}/commonvalidity/stage_mask_common.txt[] |
| |
| :stageMaskName: dstStageMask |
| include::{chapters}/commonvalidity/stage_mask_common.txt[] |
| include::{chapters}/commonvalidity/fine_sync_commands_common.txt[] |
| include::{chapters}/commonvalidity/pipeline_barrier_common.txt[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdPipelineBarrier.txt[] |
| -- |
| |
| [open,refpage='VkDependencyFlagBits',desc='Bitmask specifying how execution and memory dependencies are formed',type='enums'] |
| -- |
| Bits which can: be set in fname:vkCmdPipelineBarrier::pname:dependencyFlags, |
| specifying how execution and memory dependencies are formed, are: |
| |
| include::{generated}/api/enums/VkDependencyFlagBits.txt[] |
| |
| * ename:VK_DEPENDENCY_BY_REGION_BIT specifies that dependencies will be |
| <<synchronization-framebuffer-regions, framebuffer-local>>. |
| ifdef::VK_VERSION_1_1,VK_KHR_multiview[] |
| * ename:VK_DEPENDENCY_VIEW_LOCAL_BIT specifies that a |
| <<synchronization-pipeline-barriers-subpass-self-dependencies, subpass |
| has more than one view>>. |
| endif::VK_VERSION_1_1,VK_KHR_multiview[] |
| ifdef::VK_VERSION_1_1,VK_KHR_device_group[] |
| * ename:VK_DEPENDENCY_DEVICE_GROUP_BIT specifies that dependencies are |
| <<synchronization-device-local-dependencies, non-device-local>>. |
| endif::VK_VERSION_1_1,VK_KHR_device_group[] |
| -- |
| |
| [open,refpage='VkDependencyFlags',desc='Bitmask of VkDependencyFlagBits',type='flags'] |
| -- |
| include::{generated}/api/flags/VkDependencyFlags.txt[] |
| |
| tname:VkDependencyFlags is a bitmask type for setting a mask of zero or more |
| elink:VkDependencyFlagBits. |
| -- |
| |
| |
| [[synchronization-pipeline-barriers-subpass-self-dependencies]] |
| === Subpass Self-dependency |
| |
| ifdef::VK_KHR_dynamic_rendering[] |
| flink:vkCmdPipelineBarrier |
| ifdef::VK_KHR_synchronization2[] |
| or flink:vkCmdPipelineBarrier2KHR |
| endif::VK_KHR_synchronization2[] |
| must: not be called within a render pass instance started with |
| flink:vkCmdBeginRenderingKHR. |
| endif::VK_KHR_dynamic_rendering[] |
| |
| If flink:vkCmdPipelineBarrier |
| ifdef::VK_KHR_synchronization2[] |
| or flink:vkCmdPipelineBarrier2KHR |
| endif::VK_KHR_synchronization2[] |
| is called inside a render pass instance, the following restrictions apply. |
| For a given subpass to allow a pipeline barrier, the render pass must: |
| declare a _self-dependency_ from that subpass to itself. |
| That is, there must: exist a subpass dependency with pname:srcSubpass and |
| pname:dstSubpass both equal to that subpass index. |
| More than one self-dependency can: be declared for each subpass. |
| |
| Self-dependencies must: only include pipeline stage bits that are graphics |
| stages. |
| If any of the stages in pname:srcStageMask are |
| <<synchronization-framebuffer-regions,framebuffer-space stages>>, |
| pname:dstStageMask must: only contain |
| <<synchronization-framebuffer-regions,framebuffer-space stages>>. |
| This means that pseudo-stages like ename:VK_PIPELINE_STAGE_ALL_COMMANDS_BIT |
| which include the execution of both framebuffer-space stages and |
| non-framebuffer-space stages must: not be used. |
| |
| If the source and destination stage masks both include framebuffer-space |
| stages, then pname:dependencyFlags must: include |
| ename:VK_DEPENDENCY_BY_REGION_BIT. |
| ifdef::VK_VERSION_1_1,VK_KHR_multiview[] |
| If the subpass has more than one view, then pname:dependencyFlags must: |
| include ename:VK_DEPENDENCY_VIEW_LOCAL_BIT. |
| endif::VK_VERSION_1_1,VK_KHR_multiview[] |
| |
| Each of the <<synchronization-dependencies-scopes, synchronization scopes>> |
| and <<synchronization-dependencies-access-scopes, access scopes>> of a |
| ifdef::VK_KHR_synchronization2[] |
| flink:vkCmdPipelineBarrier2KHR or |
| endif::VK_KHR_synchronization2[] |
| flink:vkCmdPipelineBarrier command inside a render pass instance must: be a |
| subset of the scopes of one of the self-dependencies for the current |
| subpass. |
| |
| If the self-dependency has ename:VK_DEPENDENCY_BY_REGION_BIT |
| ifdef::VK_VERSION_1_1,VK_KHR_multiview[] |
| or ename:VK_DEPENDENCY_VIEW_LOCAL_BIT |
| endif::VK_VERSION_1_1,VK_KHR_multiview[] |
| set, then so must: the pipeline barrier. |
| Pipeline barriers within a render pass instance must: not include buffer |
| memory barriers. |
| Image memory barriers must: only specify image subresources that are used as |
| attachments within the subpass, and must: not define an |
| <<synchronization-image-layout-transitions, image layout transition>> or |
| <<synchronization-queue-transfers, queue family ownership transfer>>. |
| |
| |
| [[synchronization-memory-barriers]] |
| == Memory Barriers |
| |
| _Memory barriers_ are used to explicitly control access to buffer and image |
| subresource ranges. |
| Memory barriers are used to <<synchronization-queue-transfers, transfer |
| ownership between queue families>>, |
| <<synchronization-image-layout-transitions, change image layouts>>, and |
| define <<synchronization-dependencies-available-and-visible, availability |
| and visibility operations>>. |
| They explicitly define the <<synchronization-access-types, access types>> |
| and buffer and image subresource ranges that are included in the |
| <<synchronization-dependencies-access-scopes, access scopes>> of a memory |
| dependency that is created by a synchronization command that includes them. |
| |
| |
| [[synchronization-global-memory-barriers]] |
| === Global Memory Barriers |
| |
| Global memory barriers apply to memory accesses involving all memory objects |
| that exist at the time of its execution. |
| |
| ifdef::VK_KHR_synchronization2[] |
| [open,refpage='VkMemoryBarrier2KHR',desc='Structure specifying a global memory barrier',type='structs'] |
| -- |
| :refpage: VkMemoryBarrier2KHR |
| |
| The sname:VkMemoryBarrier2KHR structure is defined as: |
| |
| include::{generated}/api/structs/VkMemoryBarrier2KHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:srcStageMask is a tlink:VkPipelineStageFlags2KHR mask of pipeline |
| stages to be included in the <<synchronization-dependencies-scopes, |
| first synchronization scope>>. |
| * pname:srcAccessMask is a tlink:VkAccessFlags2KHR mask of access flags to |
| be included in the <<synchronization-dependencies-access-scopes, first |
| access scope>>. |
| * pname:dstStageMask is a tlink:VkPipelineStageFlags2KHR mask of pipeline |
| stages to be included in the <<synchronization-dependencies-scopes, |
| second synchronization scope>>. |
| * pname:dstAccessMask is a tlink:VkAccessFlags2KHR mask of access flags to |
| be included in the <<synchronization-dependencies-access-scopes, second |
| access scope>>. |
| |
| This structure defines a <<synchronization-dependencies-memory, memory |
| dependency>> affecting all device memory. |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> and |
| <<synchronization-dependencies-access-scopes, access scope>> described by |
| this structure include only operations and memory accesses specified by |
| pname:srcStageMask and pname:srcAccessMask. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| and <<synchronization-dependencies-access-scopes, access scope>> described |
| by this structure include only operations and memory accesses specified by |
| pname:dstStageMask and pname:dstAccessMask. |
| |
| .Valid Usage |
| **** |
| :stageMaskName: srcStageMask |
| :accessMaskName: srcAccessMask |
| include::{chapters}/commonvalidity/stage_mask_2_common.txt[] |
| include::{chapters}/commonvalidity/access_mask_2_common.txt[] |
| |
| :stageMaskName: dstStageMask |
| :accessMaskName: dstAccessMask |
| include::{chapters}/commonvalidity/stage_mask_2_common.txt[] |
| include::{chapters}/commonvalidity/access_mask_2_common.txt[] |
| **** |
| |
| include::{generated}/validity/structs/VkMemoryBarrier2KHR.txt[] |
| -- |
| endif::VK_KHR_synchronization2[] |
| |
| [open,refpage='VkMemoryBarrier',desc='Structure specifying a global memory barrier',type='structs'] |
| -- |
| The sname:VkMemoryBarrier structure is defined as: |
| |
| include::{generated}/api/structs/VkMemoryBarrier.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:srcAccessMask is a bitmask of elink:VkAccessFlagBits specifying a |
| <<synchronization-access-masks, source access mask>>. |
| * pname:dstAccessMask is a bitmask of elink:VkAccessFlagBits specifying a |
| <<synchronization-access-masks, destination access mask>>. |
| |
| The first <<synchronization-dependencies-access-scopes, access scope>> is |
| limited to access types in the <<synchronization-access-masks, source access |
| mask>> specified by pname:srcAccessMask. |
| |
| The second <<synchronization-dependencies-access-scopes, access scope>> is |
| limited to access types in the <<synchronization-access-masks, destination |
| access mask>> specified by pname:dstAccessMask. |
| |
| include::{generated}/validity/structs/VkMemoryBarrier.txt[] |
| -- |
| |
| |
| [[synchronization-buffer-memory-barriers]] |
| === Buffer Memory Barriers |
| |
| Buffer memory barriers only apply to memory accesses involving a specific |
| buffer range. |
| That is, a memory dependency formed from a buffer memory barrier is |
| <<synchronization-dependencies-access-scopes, scoped>> to access via the |
| specified buffer range. |
| Buffer memory barriers can: also be used to define a |
| <<synchronization-queue-transfers, queue family ownership transfer>> for the |
| specified buffer range. |
| |
| ifdef::VK_KHR_synchronization2[] |
| [open,refpage='VkBufferMemoryBarrier2KHR',desc='Structure specifying a buffer memory barrier',type='structs'] |
| -- |
| :refpage: VkBufferMemoryBarrier2KHR |
| |
| The sname:VkBufferMemoryBarrier2KHR structure is defined as: |
| |
| include::{generated}/api/structs/VkBufferMemoryBarrier2KHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:srcStageMask is a tlink:VkPipelineStageFlags2KHR mask of pipeline |
| stages to be included in the <<synchronization-dependencies-scopes, |
| first synchronization scope>>. |
| * pname:srcAccessMask is a tlink:VkAccessFlags2KHR mask of access flags to |
| be included in the <<synchronization-dependencies-access-scopes, first |
| access scope>>. |
| * pname:dstStageMask is a tlink:VkPipelineStageFlags2KHR mask of pipeline |
| stages to be included in the <<synchronization-dependencies-scopes, |
| second synchronization scope>>. |
| * pname:dstAccessMask is a tlink:VkAccessFlags2KHR mask of access flags to |
| be included in the <<synchronization-dependencies-access-scopes, second |
| access scope>>. |
| * pname:srcQueueFamilyIndex is the source queue family for a |
| <<synchronization-queue-transfers, queue family ownership transfer>>. |
| * pname:dstQueueFamilyIndex is the destination queue family for a |
| <<synchronization-queue-transfers, queue family ownership transfer>>. |
| * pname:buffer is a handle to the buffer whose backing memory is affected |
| by the barrier. |
| * pname:offset is an offset in bytes into the backing memory for |
| pname:buffer; this is relative to the base offset as bound to the buffer |
| (see flink:vkBindBufferMemory). |
| * pname:size is a size in bytes of the affected area of backing memory for |
| pname:buffer, or ename:VK_WHOLE_SIZE to use the range from pname:offset |
| to the end of the buffer. |
| |
| This structure defines a <<synchronization-dependencies-memory, memory |
| dependency>> limited to a range of a buffer, and can: define a |
| <<synchronization-queue-transfers, queue family transfer operation>> for |
| that range. |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> and |
| <<synchronization-dependencies-access-scopes, access scope>> described by |
| this structure include only operations and memory accesses specified by |
| pname:srcStageMask and pname:srcAccessMask. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| and <<synchronization-dependencies-access-scopes, access scope>> described |
| by this structure include only operations and memory accesses specified by |
| pname:dstStageMask and pname:dstAccessMask. |
| |
| Both <<synchronization-dependencies-access-scopes, access scopes>> are |
| limited to only memory accesses to pname:buffer in the range defined by |
| pname:offset and pname:size. |
| |
| If pname:buffer was created with ename:VK_SHARING_MODE_EXCLUSIVE, and |
| pname:srcQueueFamilyIndex is not equal to pname:dstQueueFamilyIndex, this |
| memory barrier defines a <<synchronization-queue-transfers, queue family |
| transfer operation>>. |
| When executed on a queue in the family identified by |
| pname:srcQueueFamilyIndex, this barrier defines a |
| <<synchronization-queue-transfers-release, queue family release operation>> |
| for the specified buffer range, and the second synchronization and access |
| scopes do not synchronize operations on that queue. |
| When executed on a queue in the family identified by |
| pname:dstQueueFamilyIndex, this barrier defines a |
| <<synchronization-queue-transfers-acquire, queue family acquire operation>> |
| for the specified buffer range, and the first synchronization and access |
| scopes do not synchronize operations on that queue. |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_memory[] |
| A <<synchronization-queue-transfers, queue family transfer operation>> is |
| also defined if the values are not equal, and either is one of the special |
| queue family values reserved for external memory ownership transfers, as |
| described in <<synchronization-queue-transfers>>. |
| A <<synchronization-queue-transfers-release, queue family release |
| operation>> is defined when pname:dstQueueFamilyIndex is one of those |
| values, and a <<synchronization-queue-transfers-acquire, queue family |
| acquire operation>> is defined when pname:srcQueueFamilyIndex is one of |
| those values. |
| endif::VK_VERSION_1_1,VK_KHR_external_memory[] |
| |
| |
| .Valid Usage |
| **** |
| |
| :stageMaskName: srcStageMask |
| :accessMaskName: srcAccessMask |
| include::{chapters}/commonvalidity/stage_mask_2_common.txt[] |
| include::{chapters}/commonvalidity/access_mask_2_common.txt[] |
| |
| :stageMaskName: dstStageMask |
| :accessMaskName: dstAccessMask |
| include::{chapters}/commonvalidity/stage_mask_2_common.txt[] |
| include::{chapters}/commonvalidity/access_mask_2_common.txt[] |
| include::{chapters}/commonvalidity/buffer_memory_barrier_common.txt[] |
| * [[VUID-VkBufferMemoryBarrier2KHR-srcStageMask-03851]] |
| If either pname:srcStageMask or pname:dstStageMask includes |
| ename:VK_PIPELINE_STAGE_2_HOST_BIT_KHR, pname:srcQueueFamilyIndex and |
| pname:dstQueueFamilyIndex must: be equal |
| **** |
| |
| include::{generated}/validity/structs/VkBufferMemoryBarrier2KHR.txt[] |
| -- |
| endif::VK_KHR_synchronization2[] |
| |
| [open,refpage='VkBufferMemoryBarrier',desc='Structure specifying a buffer memory barrier',type='structs'] |
| -- |
| :refpage: VkBufferMemoryBarrier |
| |
| The sname:VkBufferMemoryBarrier structure is defined as: |
| |
| include::{generated}/api/structs/VkBufferMemoryBarrier.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:srcAccessMask is a bitmask of elink:VkAccessFlagBits specifying a |
| <<synchronization-access-masks, source access mask>>. |
| * pname:dstAccessMask is a bitmask of elink:VkAccessFlagBits specifying a |
| <<synchronization-access-masks, destination access mask>>. |
| * pname:srcQueueFamilyIndex is the source queue family for a |
| <<synchronization-queue-transfers, queue family ownership transfer>>. |
| * pname:dstQueueFamilyIndex is the destination queue family for a |
| <<synchronization-queue-transfers, queue family ownership transfer>>. |
| * pname:buffer is a handle to the buffer whose backing memory is affected |
| by the barrier. |
| * pname:offset is an offset in bytes into the backing memory for |
| pname:buffer; this is relative to the base offset as bound to the buffer |
| (see flink:vkBindBufferMemory). |
| * pname:size is a size in bytes of the affected area of backing memory for |
| pname:buffer, or ename:VK_WHOLE_SIZE to use the range from pname:offset |
| to the end of the buffer. |
| |
| The first <<synchronization-dependencies-access-scopes, access scope>> is |
| limited to access to memory through the specified buffer range, via access |
| types in the <<synchronization-access-masks, source access mask>> specified |
| by pname:srcAccessMask. |
| If pname:srcAccessMask includes ename:VK_ACCESS_HOST_WRITE_BIT, memory |
| writes performed by that access type are also made visible, as that access |
| type is not performed through a resource. |
| |
| The second <<synchronization-dependencies-access-scopes, access scope>> is |
| limited to access to memory through the specified buffer range, via access |
| types in the <<synchronization-access-masks, destination access mask>> |
| specified by pname:dstAccessMask. |
| If pname:dstAccessMask includes ename:VK_ACCESS_HOST_WRITE_BIT or |
| ename:VK_ACCESS_HOST_READ_BIT, available memory writes are also made visible |
| to accesses of those types, as those access types are not performed through |
| a resource. |
| |
| If pname:srcQueueFamilyIndex is not equal to pname:dstQueueFamilyIndex, and |
| pname:srcQueueFamilyIndex is equal to the current queue family, then the |
| memory barrier defines a <<synchronization-queue-transfers-release, queue |
| family release operation>> for the specified buffer range, and the second |
| access scope includes no access, as if pname:dstAccessMask was `0`. |
| |
| If pname:dstQueueFamilyIndex is not equal to pname:srcQueueFamilyIndex, and |
| pname:dstQueueFamilyIndex is equal to the current queue family, then the |
| memory barrier defines a <<synchronization-queue-transfers-acquire, queue |
| family acquire operation>> for the specified buffer range, and the first |
| access scope includes no access, as if pname:srcAccessMask was `0`. |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/buffer_memory_barrier_common.txt[] |
| ifndef::VK_VERSION_1_1,VK_KHR_external_memory[] |
| * [[VUID-VkBufferMemoryBarrier-synchronization2-03852]] |
| If the <<features-synchronization2,pname:synchronization2 feature>> is |
| not enabled, and pname:buffer was created with a sharing mode of |
| ename:VK_SHARING_MODE_CONCURRENT, pname:srcQueueFamilyIndex and |
| pname:dstQueueFamilyIndex must: both be ename:VK_QUEUE_FAMILY_IGNORED |
| endif::VK_VERSION_1_1,VK_KHR_external_memory[] |
| ifdef::VK_VERSION_1_1,VK_KHR_external_memory[] |
| * [[VUID-VkBufferMemoryBarrier-synchronization2-03853]] |
| If the <<features-synchronization2,pname:synchronization2 feature>> is |
| not enabled, and pname:buffer was created with a sharing mode of |
| ename:VK_SHARING_MODE_CONCURRENT, at least one of |
| pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex must: be |
| ename:VK_QUEUE_FAMILY_IGNORED |
| endif::VK_VERSION_1_1,VK_KHR_external_memory[] |
| **** |
| |
| include::{generated}/validity/structs/VkBufferMemoryBarrier.txt[] |
| -- |
| |
| [open,refpage='VK_WHOLE_SIZE',desc='Sentinel value to use entire remaining array length',type='consts'] |
| -- |
| ename:VK_WHOLE_SIZE is a special value indicating that the entire remaining |
| length of a buffer following a given pname:offset should be used. |
| It can: be specified for slink:VkBufferMemoryBarrier::pname:size and other |
| structures. |
| |
| include::{generated}/api/enums/VK_WHOLE_SIZE.txt[] |
| -- |
| |
| |
| [[synchronization-image-memory-barriers]] |
| === Image Memory Barriers |
| |
| Image memory barriers only apply to memory accesses involving a specific |
| image subresource range. |
| That is, a memory dependency formed from an image memory barrier is |
| <<synchronization-dependencies-access-scopes, scoped>> to access via the |
| specified image subresource range. |
| Image memory barriers can: also be used to define |
| <<synchronization-image-layout-transitions, image layout transitions>> or a |
| <<synchronization-queue-transfers, queue family ownership transfer>> for the |
| specified image subresource range. |
| |
| ifdef::VK_KHR_synchronization2[] |
| [open,refpage='VkImageMemoryBarrier2KHR',desc='Structure specifying an image memory barrier',type='structs'] |
| -- |
| :refpage: VkImageMemoryBarrier2KHR |
| |
| The sname:VkImageMemoryBarrier2KHR structure is defined as: |
| |
| include::{generated}/api/structs/VkImageMemoryBarrier2KHR.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:srcStageMask is a tlink:VkPipelineStageFlags2KHR mask of pipeline |
| stages to be included in the <<synchronization-dependencies-scopes, |
| first synchronization scope>>. |
| * pname:srcAccessMask is a tlink:VkAccessFlags2KHR mask of access flags to |
| be included in the <<synchronization-dependencies-access-scopes, first |
| access scope>>. |
| * pname:dstStageMask is a tlink:VkPipelineStageFlags2KHR mask of pipeline |
| stages to be included in the <<synchronization-dependencies-scopes, |
| second synchronization scope>>. |
| * pname:dstAccessMask is a tlink:VkAccessFlags2KHR mask of access flags to |
| be included in the <<synchronization-dependencies-access-scopes, second |
| access scope>>. |
| * pname:oldLayout is the old layout in an |
| <<synchronization-image-layout-transitions, image layout transition>>. |
| * pname:newLayout is the new layout in an |
| <<synchronization-image-layout-transitions, image layout transition>>. |
| * pname:srcQueueFamilyIndex is the source queue family for a |
| <<synchronization-queue-transfers, queue family ownership transfer>>. |
| * pname:dstQueueFamilyIndex is the destination queue family for a |
| <<synchronization-queue-transfers, queue family ownership transfer>>. |
| * pname:image is a handle to the image affected by this barrier. |
| * pname:subresourceRange describes the <<resources-image-views, image |
| subresource range>> within pname:image that is affected by this barrier. |
| |
| This structure defines a <<synchronization-dependencies-memory, memory |
| dependency>> limited to an image subresource range, and can: define a |
| <<synchronization-queue-transfers, queue family transfer operation>> and |
| <<synchronization-image-layout-transitions, image layout transition>> for |
| that subresource range. |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> and |
| <<synchronization-dependencies-access-scopes, access scope>> described by |
| this structure include only operations and memory accesses specified by |
| pname:srcStageMask and pname:srcAccessMask. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| and <<synchronization-dependencies-access-scopes, access scope>> described |
| by this structure include only operations and memory accesses specified by |
| pname:dstStageMask and pname:dstAccessMask. |
| |
| Both <<synchronization-dependencies-access-scopes, access scopes>> are |
| limited to only memory accesses to pname:image in the subresource range |
| defined by pname:subresourceRange. |
| |
| If pname:image was created with ename:VK_SHARING_MODE_EXCLUSIVE, and |
| pname:srcQueueFamilyIndex is not equal to pname:dstQueueFamilyIndex, this |
| memory barrier defines a <<synchronization-queue-transfers, queue family |
| transfer operation>>. |
| When executed on a queue in the family identified by |
| pname:srcQueueFamilyIndex, this barrier defines a |
| <<synchronization-queue-transfers-release, queue family release operation>> |
| for the specified image subresource range, and the second synchronization |
| and access scopes do not synchronize operations on that queue. |
| When executed on a queue in the family identified by |
| pname:dstQueueFamilyIndex, this barrier defines a |
| <<synchronization-queue-transfers-acquire, queue family acquire operation>> |
| for the specified image subresource range, and the first synchronization and |
| access scopes do not synchronize operations on that queue. |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_memory[] |
| A <<synchronization-queue-transfers, queue family transfer operation>> is |
| also defined if the values are not equal, and either is one of the special |
| queue family values reserved for external memory ownership transfers, as |
| described in <<synchronization-queue-transfers>>. |
| A <<synchronization-queue-transfers-release, queue family release |
| operation>> is defined when pname:dstQueueFamilyIndex is one of those |
| values, and a <<synchronization-queue-transfers-acquire, queue family |
| acquire operation>> is defined when pname:srcQueueFamilyIndex is one of |
| those values. |
| endif::VK_VERSION_1_1,VK_KHR_external_memory[] |
| |
| If pname:oldLayout is not equal to pname:newLayout, then the memory barrier |
| defines an <<synchronization-image-layout-transitions, image layout |
| transition>> for the specified image subresource range. |
| If this memory barrier defines a <<synchronization-queue-transfers, queue |
| family transfer operation>>, the layout transition is only executed once |
| between the queues. |
| |
| [NOTE] |
| .Note |
| ==== |
| When the old and new layout are equal, the layout values are ignored - data |
| is preserved no matter what values are specified, or what layout the image |
| is currently in. |
| ==== |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] |
| |
| If pname:image has a multi-planar format and the image is _disjoint_, then |
| including ename:VK_IMAGE_ASPECT_COLOR_BIT in the pname:aspectMask member of |
| pname:subresourceRange is equivalent to including |
| ename:VK_IMAGE_ASPECT_PLANE_0_BIT, ename:VK_IMAGE_ASPECT_PLANE_1_BIT, and |
| (for three-plane formats only) ename:VK_IMAGE_ASPECT_PLANE_2_BIT. |
| |
| endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] |
| |
| .Valid Usage |
| **** |
| |
| :stageMaskName: srcStageMask |
| :accessMaskName: srcAccessMask |
| include::{chapters}/commonvalidity/stage_mask_2_common.txt[] |
| include::{chapters}/commonvalidity/access_mask_2_common.txt[] |
| |
| :stageMaskName: dstStageMask |
| :accessMaskName: dstAccessMask |
| include::{chapters}/commonvalidity/stage_mask_2_common.txt[] |
| include::{chapters}/commonvalidity/access_mask_2_common.txt[] |
| include::{chapters}/commonvalidity/image_memory_barrier_common.txt[] |
| * [[VUID-VkImageMemoryBarrier2KHR-srcStageMask-03854]] |
| If either pname:srcStageMask or pname:dstStageMask includes |
| ename:VK_PIPELINE_STAGE_2_HOST_BIT_KHR, pname:srcQueueFamilyIndex and |
| pname:dstQueueFamilyIndex must: be equal |
| * [[VUID-VkImageMemoryBarrier2KHR-srcStageMask-03855]] |
| If pname:srcStageMask includes ename:VK_PIPELINE_STAGE_2_HOST_BIT_KHR, |
| and pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex define a |
| <<synchronization-queue-transfers, queue family ownership transfer>> or |
| pname:oldLayout and pname:newLayout define an |
| <<synchronization-image-layout-transitions, image layout transition>>, |
| pname:oldLayout must: be one of ename:VK_IMAGE_LAYOUT_PREINITIALIZED, |
| ename:VK_IMAGE_LAYOUT_UNDEFINED, or ename:VK_IMAGE_LAYOUT_GENERAL |
| **** |
| |
| include::{generated}/validity/structs/VkImageMemoryBarrier2KHR.txt[] |
| -- |
| endif::VK_KHR_synchronization2[] |
| |
| [open,refpage='VkImageMemoryBarrier',desc='Structure specifying the parameters of an image memory barrier',type='structs'] |
| -- |
| :refpage: VkImageMemoryBarrier |
| |
| The sname:VkImageMemoryBarrier structure is defined as: |
| |
| include::{generated}/api/structs/VkImageMemoryBarrier.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:srcAccessMask is a bitmask of elink:VkAccessFlagBits specifying a |
| <<synchronization-access-masks, source access mask>>. |
| * pname:dstAccessMask is a bitmask of elink:VkAccessFlagBits specifying a |
| <<synchronization-access-masks, destination access mask>>. |
| * pname:oldLayout is the old layout in an |
| <<synchronization-image-layout-transitions, image layout transition>>. |
| * pname:newLayout is the new layout in an |
| <<synchronization-image-layout-transitions, image layout transition>>. |
| * pname:srcQueueFamilyIndex is the source queue family for a |
| <<synchronization-queue-transfers, queue family ownership transfer>>. |
| * pname:dstQueueFamilyIndex is the destination queue family for a |
| <<synchronization-queue-transfers, queue family ownership transfer>>. |
| * pname:image is a handle to the image affected by this barrier. |
| * pname:subresourceRange describes the <<resources-image-views, image |
| subresource range>> within pname:image that is affected by this barrier. |
| |
| The first <<synchronization-dependencies-access-scopes, access scope>> is |
| limited to access to memory through the specified image subresource range, |
| via access types in the <<synchronization-access-masks, source access mask>> |
| specified by pname:srcAccessMask. |
| If pname:srcAccessMask includes ename:VK_ACCESS_HOST_WRITE_BIT, memory |
| writes performed by that access type are also made visible, as that access |
| type is not performed through a resource. |
| |
| The second <<synchronization-dependencies-access-scopes, access scope>> is |
| limited to access to memory through the specified image subresource range, |
| via access types in the <<synchronization-access-masks, destination access |
| mask>> specified by pname:dstAccessMask. |
| If pname:dstAccessMask includes ename:VK_ACCESS_HOST_WRITE_BIT or |
| ename:VK_ACCESS_HOST_READ_BIT, available memory writes are also made visible |
| to accesses of those types, as those access types are not performed through |
| a resource. |
| |
| If pname:srcQueueFamilyIndex is not equal to pname:dstQueueFamilyIndex, and |
| pname:srcQueueFamilyIndex is equal to the current queue family, then the |
| memory barrier defines a <<synchronization-queue-transfers-release, queue |
| family release operation>> for the specified image subresource range, and |
| the second access scope includes no access, as if pname:dstAccessMask was |
| `0`. |
| |
| If pname:dstQueueFamilyIndex is not equal to pname:srcQueueFamilyIndex, and |
| pname:dstQueueFamilyIndex is equal to the current queue family, then the |
| memory barrier defines a <<synchronization-queue-transfers-acquire, queue |
| family acquire operation>> for the specified image subresource range, and |
| the first access scope includes no access, as if pname:srcAccessMask was |
| `0`. |
| |
| ifdef::VK_KHR_synchronization2[] |
| If the <<features-synchronization2,pname:synchronization2 feature>> is not |
| enabled or pname:oldLayout is not equal to pname:newLayout, |
| endif::VK_KHR_synchronization2[] |
| pname:oldLayout and pname:newLayout define an |
| <<synchronization-image-layout-transitions, image layout transition>> for |
| the specified image subresource range. |
| |
| ifdef::VK_KHR_synchronization2[] |
| [NOTE] |
| .Note |
| ==== |
| If the <<features-synchronization2,pname:synchronization2 feature>> is |
| enabled, when the old and new layout are equal, the layout values are |
| ignored - data is preserved no matter what values are specified, or what |
| layout the image is currently in. |
| ==== |
| endif::VK_KHR_synchronization2[] |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] |
| |
| If pname:image has a multi-planar format and the image is _disjoint_, then |
| including ename:VK_IMAGE_ASPECT_COLOR_BIT in the pname:aspectMask member of |
| pname:subresourceRange is equivalent to including |
| ename:VK_IMAGE_ASPECT_PLANE_0_BIT, ename:VK_IMAGE_ASPECT_PLANE_1_BIT, and |
| (for three-plane formats only) ename:VK_IMAGE_ASPECT_PLANE_2_BIT. |
| |
| endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/image_memory_barrier_common.txt[] |
| ifndef::VK_VERSION_1_1,VK_KHR_external_memory[] |
| * [[VUID-VkImageMemoryBarrier-synchronization2-03856]] |
| If the <<features-synchronization2,pname:synchronization2 feature>> is |
| not enabled, and pname:image was created with a sharing mode of |
| ename:VK_SHARING_MODE_CONCURRENT, pname:srcQueueFamilyIndex and |
| pname:dstQueueFamilyIndex must: both be ename:VK_QUEUE_FAMILY_IGNORED |
| endif::VK_VERSION_1_1,VK_KHR_external_memory[] |
| ifdef::VK_VERSION_1_1,VK_KHR_external_memory[] |
| * [[VUID-VkImageMemoryBarrier-synchronization2-03857]] |
| If the <<features-synchronization2,pname:synchronization2 feature>> is |
| not enabled, and pname:image was created with a sharing mode of |
| ename:VK_SHARING_MODE_CONCURRENT, at least one of |
| pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex must: be |
| ename:VK_QUEUE_FAMILY_IGNORED |
| endif::VK_VERSION_1_1,VK_KHR_external_memory[] |
| **** |
| |
| include::{generated}/validity/structs/VkImageMemoryBarrier.txt[] |
| -- |
| |
| |
| [[synchronization-queue-transfers]] |
| === Queue Family Ownership Transfer |
| |
| Resources created with a elink:VkSharingMode of |
| ename:VK_SHARING_MODE_EXCLUSIVE must: have their ownership explicitly |
| transferred from one queue family to another in order to access their |
| content in a well-defined manner on a queue in a different queue family. |
| |
| [open,refpage='VK_QUEUE_FAMILY_IGNORED',desc='Ignored queue family index sentinel',type='consts'] |
| -- |
| The special queue family index ename:VK_QUEUE_FAMILY_IGNORED indicates that |
| a queue family parameter or member is ignored. |
| |
| include::{generated}/api/enums/VK_QUEUE_FAMILY_IGNORED.txt[] |
| -- |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_external_memory[] |
| Resources shared with external APIs or instances using external memory must: |
| also explicitly manage ownership transfers between local and external queues |
| (or equivalent constructs in external APIs) regardless of the |
| elink:VkSharingMode specified when creating them. |
| |
| [open,refpage='VK_QUEUE_FAMILY_EXTERNAL',desc='External queue family index sentinel',type='consts',alias='VK_QUEUE_FAMILY_EXTERNAL_KHR'] |
| -- |
| The special queue family index ename:VK_QUEUE_FAMILY_EXTERNAL represents any |
| queue external to the resource's current Vulkan instance, as long as the |
| queue uses the same underlying |
| ifdef::VK_VERSION_1_1,VK_KHR_device_group[device group or] |
| physical device, and the same driver version as the resource's |
| slink:VkDevice, as indicated by |
| slink:VkPhysicalDeviceIDProperties::pname:deviceUUID and |
| slink:VkPhysicalDeviceIDProperties::pname:driverUUID. |
| |
| include::{generated}/api/enums/VK_QUEUE_FAMILY_EXTERNAL.txt[] |
| |
| ifdef::VK_KHR_external_memory[] |
| or the equivalent |
| |
| include::{generated}/api/enums/VK_QUEUE_FAMILY_EXTERNAL_KHR.txt[] |
| endif::VK_KHR_external_memory[] |
| -- |
| |
| ifdef::VK_EXT_queue_family_foreign[] |
| [open,refpage='VK_QUEUE_FAMILY_FOREIGN_EXT',desc='Foreign queue family index sentinel',type='consts'] |
| -- |
| The special queue family index ename:VK_QUEUE_FAMILY_FOREIGN_EXT represents |
| any queue external to the resource's current Vulkan instance, regardless of |
| the queue's underlying physical device or driver version. |
| This includes, for example, queues for fixed-function image processing |
| devices, media codec devices, and display devices, as well as all queues |
| that use the same underlying |
| ifdef::VK_VERSION_1_1,VK_KHR_device_group[device group or] |
| physical device, and the same driver version as the resource's |
| slink:VkDevice. |
| |
| include::{generated}/api/enums/VK_QUEUE_FAMILY_FOREIGN_EXT.txt[] |
| -- |
| endif::VK_EXT_queue_family_foreign[] |
| endif::VK_VERSION_1_1,VK_KHR_external_memory[] |
| |
| If memory dependencies are correctly expressed between uses of such a |
| resource between two queues in different families, but no ownership transfer |
| is defined, the contents of that resource are undefined: for any read |
| accesses performed by the second queue family. |
| |
| [NOTE] |
| .Note |
| ==== |
| If an application does not need the contents of a resource to remain valid |
| when transferring from one queue family to another, then the ownership |
| transfer should: be skipped. |
| ==== |
| |
| ifdef::VK_EXT_queue_family_foreign[] |
| [NOTE] |
| .Note |
| ==== |
| Applications should expect transfers to/from |
| ename:VK_QUEUE_FAMILY_FOREIGN_EXT to be more expensive than transfers |
| to/from ename:VK_QUEUE_FAMILY_EXTERNAL_KHR. |
| ==== |
| endif::VK_EXT_queue_family_foreign[] |
| |
| A queue family ownership transfer consists of two distinct parts: |
| |
| . Release exclusive ownership from the source queue family |
| . Acquire exclusive ownership for the destination queue family |
| |
| An application must: ensure that these operations occur in the correct order |
| by defining an execution dependency between them, e.g. using a semaphore. |
| |
| [[synchronization-queue-transfers-release]] A _release operation_ is used to |
| release exclusive ownership of a range of a buffer or image subresource |
| range. |
| A release operation is defined by executing a |
| <<synchronization-buffer-memory-barriers, buffer memory barrier>> (for a |
| buffer range) or an <<synchronization-image-memory-barriers, image memory |
| barrier>> (for an image subresource range) using a pipeline barrier command, |
| on a queue from the source queue family. |
| The pname:srcQueueFamilyIndex parameter of the barrier must: be set to the |
| source queue family index, and the pname:dstQueueFamilyIndex parameter to |
| the destination queue family index. |
| pname:dstAccessMask is ignored for such a barrier, such that no visibility |
| operation is executed - the value of this mask does not affect the validity |
| of the barrier. |
| The release operation happens-after the availability operation, and |
| happens-before operations specified in the second synchronization scope of |
| the calling command. |
| |
| [[synchronization-queue-transfers-acquire]] An _acquire operation_ is used |
| to acquire exclusive ownership of a range of a buffer or image subresource |
| range. |
| An acquire operation is defined by executing a |
| <<synchronization-buffer-memory-barriers, buffer memory barrier>> (for a |
| buffer range) or an <<synchronization-image-memory-barriers, image memory |
| barrier>> (for an image subresource range) using a pipeline barrier command, |
| on a queue from the destination queue family. |
| The buffer range or image subresource range specified in an acquire |
| operation must: match exactly that of a previous release operation. |
| The pname:srcQueueFamilyIndex parameter of the barrier must: be set to the |
| source queue family index, and the pname:dstQueueFamilyIndex parameter to |
| the destination queue family index. |
| pname:srcAccessMask is ignored for such a barrier, such that no availability |
| operation is executed - the value of this mask does not affect the validity |
| of the barrier. |
| The acquire operation happens-after operations in the first synchronization |
| scope of the calling command, and happens-before the visibility operation. |
| |
| [NOTE] |
| .Note |
| ==== |
| Whilst it is not invalid to provide destination or source access masks for |
| memory barriers used for release or acquire operations, respectively, they |
| have no practical effect. |
| Access after a release operation has undefined: results, and so visibility |
| for those accesses has no practical effect. |
| Similarly, write access before an acquire operation will produce undefined: |
| results for future access, so availability of those writes has no practical |
| use. |
| In an earlier version of the specification, these were required to match on |
| both sides - but this was subsequently relaxed. |
| These masks should: be set to 0. |
| ==== |
| |
| If the transfer is via an image memory barrier, and an |
| <<synchronization-image-layout-transitions, image layout transition>> is |
| desired, then the values of pname:oldLayout and pname:newLayout in the |
| _release operation_'s memory barrier must: be equal to values of |
| pname:oldLayout and pname:newLayout in the _acquire operation_'s memory |
| barrier. |
| Although the image layout transition is submitted twice, it will only be |
| executed once. |
| A layout transition specified in this way happens-after the _release |
| operation_ and happens-before the _acquire operation_. |
| |
| If the values of pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex are |
| equal, no ownership transfer is performed, and the barrier operates as if |
| they were both set to ename:VK_QUEUE_FAMILY_IGNORED. |
| |
| Queue family ownership transfers may: perform read and write accesses on all |
| memory bound to the image subresource or buffer range, so applications must: |
| ensure that all memory writes have been made |
| <<synchronization-dependencies-available-and-visible, available>> before a |
| queue family ownership transfer is executed. |
| Available memory is automatically made visible to queue family release and |
| acquire operations, and writes performed by those operations are |
| automatically made available. |
| |
| Once a queue family has acquired ownership of a buffer range or image |
| subresource range of a ename:VK_SHARING_MODE_EXCLUSIVE resource, its |
| contents are undefined: to other queue families unless ownership is |
| transferred. |
| The contents of any portion of another resource which aliases memory that is |
| bound to the transferred buffer or image subresource range are undefined: |
| after a release or acquire operation. |
| |
| [NOTE] |
| .Note |
| ==== |
| Because <<synchronization-events, events>> cannot: be used directly for |
| inter-queue synchronization, and because flink:vkCmdSetEvent does not have |
| the queue family index or memory barrier parameters needed by a _release |
| operation_, the release and acquire operations of a queue family ownership |
| transfer can: only be performed using flink:vkCmdPipelineBarrier. |
| ==== |
| |
| |
| [[synchronization-wait-idle]] |
| == Wait Idle Operations |
| |
| [open,refpage='vkQueueWaitIdle',desc='Wait for a queue to become idle',type='protos'] |
| -- |
| To wait on the host for the completion of outstanding queue operations for a |
| given queue, call: |
| |
| include::{generated}/api/protos/vkQueueWaitIdle.txt[] |
| |
| * pname:queue is the queue on which to wait. |
| |
| fname:vkQueueWaitIdle is equivalent to having submitted a valid fence to |
| every previously executed <<devsandqueues-submission,queue submission |
| command>> that accepts a fence, then waiting for all of those fences to |
| signal using flink:vkWaitForFences with an infinite timeout and |
| pname:waitAll set to ename:VK_TRUE. |
| |
| include::{generated}/validity/protos/vkQueueWaitIdle.txt[] |
| -- |
| |
| [open,refpage='vkDeviceWaitIdle',desc='Wait for a device to become idle',type='protos'] |
| -- |
| To wait on the host for the completion of outstanding queue operations for |
| all queues on a given logical device, call: |
| |
| include::{generated}/api/protos/vkDeviceWaitIdle.txt[] |
| |
| * pname:device is the logical device to idle. |
| |
| fname:vkDeviceWaitIdle is equivalent to calling fname:vkQueueWaitIdle for |
| all queues owned by pname:device. |
| |
| include::{generated}/validity/protos/vkDeviceWaitIdle.txt[] |
| -- |
| |
| |
| [[synchronization-submission-host-writes]] |
| == Host Write Ordering Guarantees |
| |
| When batches of command buffers are submitted to a queue via a |
| <<devsandqueues-submission, queue submission command>>, it defines a memory |
| dependency with prior host operations, and execution of command buffers |
| submitted to the queue. |
| |
| The first <<synchronization-dependencies-scopes, synchronization scope>> is |
| defined by the host execution model, but includes execution of |
| flink:vkQueueSubmit on the host and anything that happened-before it. |
| |
| The second <<synchronization-dependencies-scopes, synchronization scope>> |
| includes all commands submitted in the same <<devsandqueues-submission, |
| queue submission>>, and all commands that occur later in |
| <<synchronization-submission-order,submission order>>. |
| |
| The first <<synchronization-dependencies-access-scopes, access scope>> |
| includes all host writes to mappable device memory that are available to the |
| host memory domain. |
| |
| The second <<synchronization-dependencies-access-scopes, access scope>> |
| includes all memory access performed by the device. |
| |
| |
| ifdef::VK_VERSION_1_1,VK_KHR_device_group[] |
| [[synchronization-device-group]] |
| == Synchronization and Multiple Physical Devices |
| |
| If a logical device includes more than one physical device, then fences, |
| semaphores, and events all still have a single instance of the signaled |
| state. |
| |
| A fence becomes signaled when all physical devices complete the necessary |
| queue operations. |
| |
| Semaphore wait and signal operations all include a device index that is the |
| sole physical device that performs the operation. |
| These indices are provided in the slink:VkDeviceGroupSubmitInfo and |
| slink:VkDeviceGroupBindSparseInfo structures. |
| Semaphores are not exclusively owned by any physical device. |
| For example, a semaphore can be signaled by one physical device and then |
| waited on by a different physical device. |
| |
| An event can: only be waited on by the same physical device that signaled it |
| (or the host). |
| endif::VK_VERSION_1_1,VK_KHR_device_group[] |
| |
| |
| ifdef::VK_EXT_calibrated_timestamps[] |
| [[calibrated-timestamps]] |
| == Calibrated timestamps |
| |
| [open,refpage='vkGetCalibratedTimestampsEXT',desc='Query calibrated timestamps',type='protos'] |
| -- |
| In order to be able to correlate the time a particular operation took place |
| at on timelines of different time domains (e.g. a device operation vs a host |
| operation), Vulkan allows querying calibrated timestamps from multiple time |
| domains. |
| |
| To query calibrated timestamps from a set of time domains, call: |
| |
| include::{generated}/api/protos/vkGetCalibratedTimestampsEXT.txt[] |
| |
| * pname:device is the logical device used to perform the query. |
| * pname:timestampCount is the number of timestamps to query. |
| * pname:pTimestampInfos is a pointer to an array of pname:timestampCount |
| slink:VkCalibratedTimestampInfoEXT structures, describing the time |
| domains the calibrated timestamps should be captured from. |
| * pname:pTimestamps is a pointer to an array of pname:timestampCount |
| 64-bit unsigned integer values in which the requested calibrated |
| timestamp values are returned. |
| * pname:pMaxDeviation is a pointer to a 64-bit unsigned integer value in |
| which the strictly positive maximum deviation, in nanoseconds, of the |
| calibrated timestamp values is returned. |
| |
| [NOTE] |
| .Note |
| ==== |
| The maximum deviation may: vary between calls to |
| fname:vkGetCalibratedTimestampsEXT even for the same set of time domains due |
| to implementation and platform specific reasons. |
| It is the application's responsibility to assess whether the returned |
| maximum deviation makes the timestamp values suitable for any particular |
| purpose and can: choose to re-issue the timestamp calibration call pursuing |
| a lower devation value. |
| ==== |
| |
| Calibrated timestamp values can: be extrapolated to estimate future |
| coinciding timestamp values, however, depending on the nature of the time |
| domains and other properties of the platform extrapolating values over a |
| sufficiently long period of time may: no longer be accurate enough to fit |
| any particular purpose, so applications are expected to re-calibrate the |
| timestamps on a regular basis. |
| |
| include::{generated}/validity/protos/vkGetCalibratedTimestampsEXT.txt[] |
| -- |
| |
| [open,refpage='VkCalibratedTimestampInfoEXT',desc='Structure specifying the input parameters of a calibrated timestamp query',type='structs'] |
| -- |
| The sname:VkCalibratedTimestampInfoEXT structure is defined as: |
| |
| include::{generated}/api/structs/VkCalibratedTimestampInfoEXT.txt[] |
| |
| * pname:sType is the type of this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:timeDomain is a elink:VkTimeDomainEXT value specifying the time |
| domain from which the calibrated timestamp value should be returned. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkCalibratedTimestampInfoEXT-timeDomain-02354]] |
| pname:timeDomain must: be one of the elink:VkTimeDomainEXT values |
| returned by flink:vkGetPhysicalDeviceCalibrateableTimeDomainsEXT |
| **** |
| include::{generated}/validity/structs/VkCalibratedTimestampInfoEXT.txt[] |
| -- |
| |
| [open,refpage='VkTimeDomainEXT',desc='Supported time domains',type='enums'] |
| -- |
| The set of supported time domains consists of: |
| |
| include::{generated}/api/enums/VkTimeDomainEXT.txt[] |
| |
| * ename:VK_TIME_DOMAIN_DEVICE_EXT specifies the device time domain. |
| Timestamp values in this time domain use the same units and are |
| comparable with device timestamp values captured using |
| flink:vkCmdWriteTimestamp |
| ifdef::VK_KHR_synchronization2[] |
| or flink:vkCmdWriteTimestamp2KHR |
| endif::VK_KHR_synchronization2[] |
| and are defined to be incrementing according to the |
| <<limits-timestampPeriod,timestampPeriod>> of the device. |
| |
| * ename:VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT specifies the CLOCK_MONOTONIC |
| time domain available on POSIX platforms. |
| Timestamp values in this time domain are in units of nanoseconds and are |
| comparable with platform timestamp values captured using the POSIX |
| clock_gettime API as computed by this example: |
| |
| [NOTE] |
| .Note |
| ==== |
| An implementation supporting `apiext:VK_EXT_calibrated_timestamps` will use |
| the same time domain for all its slink:VkQueue so that timestamp values |
| reported for ename:VK_TIME_DOMAIN_DEVICE_EXT can be matched to any timestamp |
| captured through flink:vkCmdWriteTimestamp |
| ifdef::VK_KHR_synchronization2[] |
| or flink:vkCmdWriteTimestamp2KHR |
| endif::VK_KHR_synchronization2[] |
| . |
| ==== |
| |
| [source,c] |
| ~~~~ |
| struct timespec tv; |
| clock_gettime(CLOCK_MONOTONIC, &tv); |
| return tv.tv_nsec + tv.tv_sec*1000000000ull; |
| ~~~~ |
| |
| * ename:VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT specifies the |
| CLOCK_MONOTONIC_RAW time domain available on POSIX platforms. |
| Timestamp values in this time domain are in units of nanoseconds and are |
| comparable with platform timestamp values captured using the POSIX |
| clock_gettime API as computed by this example: |
| |
| [source,c] |
| ~~~~ |
| struct timespec tv; |
| clock_gettime(CLOCK_MONOTONIC_RAW, &tv); |
| return tv.tv_nsec + tv.tv_sec*1000000000ull; |
| ~~~~ |
| |
| * ename:VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT specifies the |
| performance counter (QPC) time domain available on Windows. |
| Timestamp values in this time domain are in the same units as those |
| provided by the Windows QueryPerformanceCounter API and are comparable |
| with platform timestamp values captured using that API as computed by |
| this example: |
| |
| [source,c] |
| ~~~~ |
| LARGE_INTEGER counter; |
| QueryPerformanceCounter(&counter); |
| return counter.QuadPart; |
| ~~~~ |
| -- |
| endif::VK_EXT_calibrated_timestamps[] |