Browse Source

Vk: some more docs / tips for pipeline barriers.

pull/495/head
Vladimír Vondruš 5 years ago
parent
commit
22f918dffd
  1. 4
      doc/platforms-vk.dox
  2. 27
      src/Magnum/Vk/CommandBuffer.h
  3. 40
      src/Magnum/Vk/Pipeline.h

4
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 @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: NVidia tutorials and tips:
- [Engaging the Voyage to Vulkan](https://developer.nvidia.com/engaging-voyage-vulkan) - [Engaging the Voyage to Vulkan](https://developer.nvidia.com/engaging-voyage-vulkan)

27
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 * See @ref Vk-Buffer-usage-copy, @ref Vk-Image-usage-clear and
* @ref Vk-Image-usage-copy for usage examples. * @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} * @see @fn_vk_keyword{CmdPipelineBarrier}
*/ */
CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, Containers::ArrayView<const MemoryBarrier> memoryBarriers, Containers::ArrayView<const BufferMemoryBarrier> bufferMemoryBarriers, Containers::ArrayView<const ImageMemoryBarrier> imageMemoryBarriers, DependencyFlags dependencyFlags = {}); CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, Containers::ArrayView<const MemoryBarrier> memoryBarriers, Containers::ArrayView<const BufferMemoryBarrier> bufferMemoryBarriers, Containers::ArrayView<const ImageMemoryBarrier> imageMemoryBarriers, DependencyFlags dependencyFlags = {});

40
src/Magnum/Vk/Pipeline.h

@ -355,7 +355,16 @@ enum class PipelineStage: UnsignedInt {
*/ */
AllGraphics = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 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 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 * All read accesses. Valid for any @ref PipelineStage, treated as
* equivalent of a combination of all `*Read` flags valid in given context. * 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, MemoryRead = VK_ACCESS_MEMORY_READ_BIT,
@ -530,6 +546,13 @@ enum class Access: UnsignedInt {
* All write accesses. Valid for any @ref PipelineStage, treated as * All write accesses. Valid for any @ref PipelineStage, treated as
* equivalent of a combination of all `*Write` flags valid in given * equivalent of a combination of all `*Write` flags valid in given
* context. * 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, MemoryWrite = VK_ACCESS_MEMORY_WRITE_BIT,
@ -614,7 +637,10 @@ class MAGNUM_VK_EXPORT MemoryBarrier {
/** /**
* @brief Constructor * @brief Constructor
* @param sourceAccesses Source memory access types * @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 * @param destinationAccesses Destination memory access types
* participating in a dependency * participating in a dependency
* *
@ -672,7 +698,10 @@ class MAGNUM_VK_EXPORT BufferMemoryBarrier {
/** /**
* @brief Constructor * @brief Constructor
* @param sourceAccesses Source memory access types * @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 * @param destinationAccesses Destination memory access types
* participating in a dependency * participating in a dependency
* @param buffer A @ref Buffer or a raw Vulkan buffer * @param buffer A @ref Buffer or a raw Vulkan buffer
@ -740,7 +769,10 @@ class MAGNUM_VK_EXPORT ImageMemoryBarrier {
/** /**
* @brief Constructor * @brief Constructor
* @param sourceAccesses Source memory access types * @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 * @param oldLayout Old layout in an image layout
* transition * transition
* @param destinationAccesses Destination memory access types * @param destinationAccesses Destination memory access types

Loading…
Cancel
Save