diff --git a/src/Magnum/Vk/CommandBuffer.h b/src/Magnum/Vk/CommandBuffer.h index 181caec19..2ce120744 100644 --- a/src/Magnum/Vk/CommandBuffer.h +++ b/src/Magnum/Vk/CommandBuffer.h @@ -393,6 +393,39 @@ class MAGNUM_VK_EXPORT CommandBuffer { /** @overload */ CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, std::initializer_list memoryBarriers, std::initializer_list bufferMemoryBarriers, std::initializer_list imageMemoryBarriers, DependencyFlags dependencyFlags = {}); + /** + * @brief Insert a global memory dependency + * @return Reference to self (for method chaining) + * + * Equivalent to calling @ref pipelineBarrier(PipelineStages, PipelineStages, Containers::ArrayView, Containers::ArrayView, Containers::ArrayView, DependencyFlags) + * with empty @p bufferBarriers and @p imageBarriers. + */ + CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, Containers::ArrayView memoryBarriers, DependencyFlags dependencyFlags = {}); + /** @overload */ + CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, std::initializer_list memoryBarriers, DependencyFlags dependencyFlags = {}); + + /** + * @brief Insert a buffer memory dependency + * @return Reference to self (for method chaining) + * + * Equivalent to calling @ref pipelineBarrier(PipelineStages, PipelineStages, Containers::ArrayView, Containers::ArrayView, Containers::ArrayView, DependencyFlags) + * with empty @p memoryBarriers and @p imageBarriers. + */ + CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, Containers::ArrayView bufferMemoryBarriers, DependencyFlags dependencyFlags = {}); + /** @overload */ + CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, std::initializer_list bufferMemoryBarriers, DependencyFlags dependencyFlags = {}); + + /** + * @brief Insert an image memory dependency + * @return Reference to self (for method chaining) + * + * Equivalent to calling @ref pipelineBarrier(PipelineStages, PipelineStages, Containers::ArrayView, Containers::ArrayView, Containers::ArrayView, DependencyFlags) + * with empty @p memoryBarriers and @p bufferBarriers. + */ + CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, Containers::ArrayView imageMemoryBarriers, DependencyFlags dependencyFlags = {}); + /** @overload */ + CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, std::initializer_list imageMemoryBarriers, DependencyFlags dependencyFlags = {}); + private: friend CommandPool; friend Implementation::DeviceState; diff --git a/src/Magnum/Vk/Pipeline.cpp b/src/Magnum/Vk/Pipeline.cpp index d942c204c..54e0e837a 100644 --- a/src/Magnum/Vk/Pipeline.cpp +++ b/src/Magnum/Vk/Pipeline.cpp @@ -98,4 +98,28 @@ CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages, return pipelineBarrier(sourceStages, destinationStages, Containers::arrayView(memoryBarriers), Containers::arrayView(bufferMemoryBarriers), Containers::arrayView(imageMemoryBarriers), dependencyFlags); } +CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages, const PipelineStages destinationStages, const Containers::ArrayView memoryBarriers, const DependencyFlags dependencyFlags) { + return pipelineBarrier(sourceStages, destinationStages, memoryBarriers, {}, {}, dependencyFlags); +} + +CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages, const PipelineStages destinationStages, const std::initializer_list memoryBarriers, const DependencyFlags dependencyFlags) { + return pipelineBarrier(sourceStages, destinationStages, Containers::arrayView(memoryBarriers), dependencyFlags); +} + +CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages, const PipelineStages destinationStages, const Containers::ArrayView bufferMemoryBarriers, const DependencyFlags dependencyFlags) { + return pipelineBarrier(sourceStages, destinationStages, {}, bufferMemoryBarriers, {}, dependencyFlags); +} + +CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages, const PipelineStages destinationStages, const std::initializer_list bufferMemoryBarriers, const DependencyFlags dependencyFlags) { + return pipelineBarrier(sourceStages, destinationStages, Containers::arrayView(bufferMemoryBarriers), dependencyFlags); +} + +CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages, const PipelineStages destinationStages, const Containers::ArrayView imageMemoryBarriers, const DependencyFlags dependencyFlags) { + return pipelineBarrier(sourceStages, destinationStages, {}, {}, imageMemoryBarriers, dependencyFlags); +} + +CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages, const PipelineStages destinationStages, const std::initializer_list imageMemoryBarriers, const DependencyFlags dependencyFlags) { + return pipelineBarrier(sourceStages, destinationStages, Containers::arrayView(imageMemoryBarriers), dependencyFlags); +} + }} diff --git a/src/Magnum/Vk/Test/PipelineVkTest.cpp b/src/Magnum/Vk/Test/PipelineVkTest.cpp index de7c91d51..8753f89a0 100644 --- a/src/Magnum/Vk/Test/PipelineVkTest.cpp +++ b/src/Magnum/Vk/Test/PipelineVkTest.cpp @@ -38,10 +38,16 @@ struct PipelineVkTest: VulkanTester { explicit PipelineVkTest(); void pipelineBarrier(); + void pipelineBarrierGeneral(); + void pipelineBarrierBuffer(); + void pipelineBarrierImage(); }; PipelineVkTest::PipelineVkTest() { - addTests({&PipelineVkTest::pipelineBarrier}); + addTests({&PipelineVkTest::pipelineBarrier, + &PipelineVkTest::pipelineBarrierGeneral, + &PipelineVkTest::pipelineBarrierBuffer, + &PipelineVkTest::pipelineBarrierImage}); } void PipelineVkTest::pipelineBarrier() { @@ -73,6 +79,64 @@ void PipelineVkTest::pipelineBarrier() { CORRADE_VERIFY(true); } +void PipelineVkTest::pipelineBarrierGeneral() { + CommandPool pool{device(), CommandPoolCreateInfo{ + device().properties().pickQueueFamily(QueueFlag::Graphics)}}; + + /* A subset of the above, just to test the convenience overloads */ + + pool.allocate() + .begin() + .pipelineBarrier(PipelineStage::Transfer, PipelineStage::Host, { + {Access::TransferWrite, Access::HostRead} + }) + .end(); + + /* Does not do anything visible, so just test that it didn't blow up */ + CORRADE_VERIFY(true); +} + +void PipelineVkTest::pipelineBarrierBuffer() { + CommandPool pool{device(), CommandPoolCreateInfo{ + device().properties().pickQueueFamily(QueueFlag::Graphics)}}; + + Buffer buffer{device(), BufferCreateInfo{ + BufferUsage::TransferDestination|BufferUsage::VertexBuffer, 16 + }, MemoryFlag::DeviceLocal}; + + pool.allocate() + .begin() + .pipelineBarrier(PipelineStage::Transfer, PipelineStage::VertexInput, { + {Access::TransferWrite, Access::VertexAttributeRead, buffer} + }) + .end(); + + /* Does not do anything visible, so just test that it didn't blow up */ + CORRADE_VERIFY(true); +} + +void PipelineVkTest::pipelineBarrierImage() { + CommandPool pool{device(), CommandPoolCreateInfo{ + device().properties().pickQueueFamily(QueueFlag::Graphics)}}; + + Image image{device(), ImageCreateInfo2D{ + ImageUsage::TransferDestination|ImageUsage::Sampled, + PixelFormat::RGBA8Unorm, {4, 4}, 1 + }, MemoryFlag::DeviceLocal}; + + pool.allocate() + .begin() + .pipelineBarrier(PipelineStage::Transfer, PipelineStage::FragmentShader, { + {Access::TransferWrite, Access::ShaderRead, + ImageLayout::Preinitialized, ImageLayout::ShaderReadOnly, + image, ImageAspect::Color} + }) + .end(); + + /* Does not do anything visible, so just test that it didn't blow up */ + CORRADE_VERIFY(true); +} + }}}} CORRADE_TEST_MAIN(Magnum::Vk::Test::PipelineVkTest)