From 22f918dffd42d11ecd1cd7cc897c75c30bf69ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 8 Feb 2021 13:31:37 +0100 Subject: [PATCH] Vk: some more docs / tips for pipeline barriers. --- doc/platforms-vk.dox | 4 ++++ src/Magnum/Vk/CommandBuffer.h | 27 +++++++++++++++++++++++ src/Magnum/Vk/Pipeline.h | 40 +++++++++++++++++++++++++++++++---- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/doc/platforms-vk.dox b/doc/platforms-vk.dox index ba6d7235b..5a06fa19f 100644 --- a/doc/platforms-vk.dox +++ b/doc/platforms-vk.dox @@ -75,6 +75,10 @@ Build as a static library and supply to CMake via `Vulkan_LIBRARY`: @section platforms-vk-best-practices Vulkan best practices +Khronos wiki: + +- [Synchronization Examples](https://github.com/KhronosGroup/Vulkan-Docs/wiki/Synchronization-Examples) + NVidia tutorials and tips: - [Engaging the Voyage to Vulkan](https://developer.nvidia.com/engaging-voyage-vulkan) diff --git a/src/Magnum/Vk/CommandBuffer.h b/src/Magnum/Vk/CommandBuffer.h index fcaa5a4f9..2ebd3345a 100644 --- a/src/Magnum/Vk/CommandBuffer.h +++ b/src/Magnum/Vk/CommandBuffer.h @@ -413,6 +413,33 @@ class MAGNUM_VK_EXPORT CommandBuffer { * * See @ref Vk-Buffer-usage-copy, @ref Vk-Image-usage-clear and * @ref Vk-Image-usage-copy for usage examples. + * + * @m_class{m-note m-success} + * + * @par + * Where possible, expressing the dependencies and image layout + * transitions via @ref RenderPass APIs is considered more + * efficient than an explicit barrier ([source](https://github.com/KhronosGroup/Vulkan-Docs/wiki/Synchronization-Examples#graphics-to-graphics-dependencies)). + * @par + * To avoid pipeline stalls and unnecessary synchronization, avoid + * using overly generic stage and access sets. On the other hand, + * using @ref PipelineStage::AllCommands together with + * @ref Access::MemoryRead / @relativeref{Access,MemoryWrite} is + * useful for debugging synchronization issues. + * @par + * According to multiple sources ([1](https://github.com/KhronosGroup/Vulkan-Docs/wiki/Synchronization-Examples#three-dispatches-first-dispatch-writes-to-one-storage-buffer-second-dispatch-writes-to-a-different-storage-buffer-third-dispatch-reads-both), + * [2](https://developer.nvidia.com/blog/vulkan-dos-donts/#h.6fr5jvul7u03)), + * it's advised to group multiple barriers together into a single + * call --- that way the worst case can be picked instead of + * sequentially going through all barriers. + * @par + * Even though it may seem counterintuitive, it's recommended + * ([1](https://github.com/KhronosGroup/Vulkan-Docs/wiki/Synchronization-Examples#three-dispatches-first-dispatch-writes-to-one-storage-buffer-second-dispatch-writes-to-a-different-storage-buffer-third-dispatch-reads-both), + * [2](http://themaister.net/blog/2019/08/14/yet-another-blog-explaining-vulkan-synchronization/)) + * to do global memory barriers than per-resource barriers, except + * for cases where layout transition or queue ownership transfer + * needs to be done on a particular image or buffer. + * * @see @fn_vk_keyword{CmdPipelineBarrier} */ CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, Containers::ArrayView memoryBarriers, Containers::ArrayView bufferMemoryBarriers, Containers::ArrayView imageMemoryBarriers, DependencyFlags dependencyFlags = {}); diff --git a/src/Magnum/Vk/Pipeline.h b/src/Magnum/Vk/Pipeline.h index 1026adb2f..1f0255e1e 100644 --- a/src/Magnum/Vk/Pipeline.h +++ b/src/Magnum/Vk/Pipeline.h @@ -355,7 +355,16 @@ enum class PipelineStage: UnsignedInt { */ AllGraphics = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, - /** All commands */ + /** + * All commands. + * + * @m_class{m-note m-success} + * + * @par + * To avoid pipeline stalls and unnecessary synchronization, it's not + * advised to use this flag except for debugging synchronization + * issues. + */ AllCommands = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT }; @@ -523,6 +532,13 @@ enum class Access: UnsignedInt { /** * All read accesses. Valid for any @ref PipelineStage, treated as * equivalent of a combination of all `*Read` flags valid in given context. + * + * @m_class{m-note m-success} + * + * @par + * To avoid pipeline stalls and unnecessary synchronization, it's not + * advised to use this flag except for debugging synchronization + * issues. */ MemoryRead = VK_ACCESS_MEMORY_READ_BIT, @@ -530,6 +546,13 @@ enum class Access: UnsignedInt { * All write accesses. Valid for any @ref PipelineStage, treated as * equivalent of a combination of all `*Write` flags valid in given * context. + * + * @m_class{m-note m-success} + * + * @par + * To avoid pipeline stalls and unnecessary synchronization, it's not + * advised to use this flag except for debugging synchronization + * issues. */ MemoryWrite = VK_ACCESS_MEMORY_WRITE_BIT, @@ -614,7 +637,10 @@ class MAGNUM_VK_EXPORT MemoryBarrier { /** * @brief Constructor * @param sourceAccesses Source memory access types - * participating in a dependency + * participating in a dependency. While allowed, passing `Read` + * accesses here is redundant --- that's already taken care of by + * the stage execution dependency in + * @ref CommandBuffer::pipelineBarrier(). * @param destinationAccesses Destination memory access types * participating in a dependency * @@ -672,7 +698,10 @@ class MAGNUM_VK_EXPORT BufferMemoryBarrier { /** * @brief Constructor * @param sourceAccesses Source memory access types - * participating in a dependency + * participating in a dependency. While allowed, passing `Read` + * accesses here is redundant --- that's already taken care of by + * the stage execution dependency in + * @ref CommandBuffer::pipelineBarrier(). * @param destinationAccesses Destination memory access types * participating in a dependency * @param buffer A @ref Buffer or a raw Vulkan buffer @@ -740,7 +769,10 @@ class MAGNUM_VK_EXPORT ImageMemoryBarrier { /** * @brief Constructor * @param sourceAccesses Source memory access types - * participating in a dependency + * participating in a dependency. While allowed, passing `Read` + * accesses here is redundant --- that's already taken care of by + * the stage execution dependency in + * @ref CommandBuffer::pipelineBarrier(). * @param oldLayout Old layout in an image layout * transition * @param destinationAccesses Destination memory access types