Browse Source

Vk: add an execution-only pipelineBarrier() overload.

Useful for WAR barriers. I also *finally* get why is it called a
pipeline barrier and not a memory barrier.
pull/494/head
Vladimír Vondruš 5 years ago
parent
commit
18cced3e6b
  1. 14
      src/Magnum/Vk/CommandBuffer.h
  2. 4
      src/Magnum/Vk/Pipeline.cpp
  3. 35
      src/Magnum/Vk/Test/PipelineVkTest.cpp

14
src/Magnum/Vk/CommandBuffer.h

@ -358,7 +358,7 @@ class MAGNUM_VK_EXPORT CommandBuffer {
#endif #endif
/** /**
* @brief Insert a memory dependency * @brief Insert an execution barrier with optional memory dependencies
* @param sourceStages Source stages. Has to contain at least * @param sourceStages Source stages. Has to contain at least
* one stage. * one stage.
* @param destinationStages Destination stages. Has to contain at * @param destinationStages Destination stages. Has to contain at
@ -395,6 +395,18 @@ class MAGNUM_VK_EXPORT CommandBuffer {
/** @overload */ /** @overload */
CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, std::initializer_list<MemoryBarrier> memoryBarriers, std::initializer_list<BufferMemoryBarrier> bufferMemoryBarriers, std::initializer_list<ImageMemoryBarrier> imageMemoryBarriers, DependencyFlags dependencyFlags = {}); CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, std::initializer_list<MemoryBarrier> memoryBarriers, std::initializer_list<BufferMemoryBarrier> bufferMemoryBarriers, std::initializer_list<ImageMemoryBarrier> imageMemoryBarriers, DependencyFlags dependencyFlags = {});
/**
* @brief Insert an execution barrier without memory dependencies
* @return Reference to self (for method chaining)
*
* Equivalent to calling @ref pipelineBarrier(PipelineStages, PipelineStages, Containers::ArrayView<const MemoryBarrier>, Containers::ArrayView<const BufferMemoryBarrier>, Containers::ArrayView<const ImageMemoryBarrier>, DependencyFlags)
* with empty @p memoryBarriers, @p bufferBarriers and
* @p imageBarriers. Useful when an execution barrier is enough, for
* example when you need reads from one stage to finish before another
* stage starts writing to the same location.
*/
CommandBuffer& pipelineBarrier(PipelineStages sourceStages, PipelineStages destinationStages, DependencyFlags dependencyFlags = {});
/** /**
* @brief Insert a global memory dependency * @brief Insert a global memory dependency
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)

4
src/Magnum/Vk/Pipeline.cpp

@ -101,6 +101,10 @@ CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages,
return pipelineBarrier(sourceStages, destinationStages, Containers::arrayView(memoryBarriers), Containers::arrayView(bufferMemoryBarriers), Containers::arrayView(imageMemoryBarriers), dependencyFlags); return pipelineBarrier(sourceStages, destinationStages, Containers::arrayView(memoryBarriers), Containers::arrayView(bufferMemoryBarriers), Containers::arrayView(imageMemoryBarriers), dependencyFlags);
} }
CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages, const PipelineStages destinationStages, const DependencyFlags dependencyFlags) {
return pipelineBarrier(sourceStages, destinationStages, {}, {}, {}, dependencyFlags);
}
CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages, const PipelineStages destinationStages, const Containers::ArrayView<const MemoryBarrier> memoryBarriers, const DependencyFlags dependencyFlags) { CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages, const PipelineStages destinationStages, const Containers::ArrayView<const MemoryBarrier> memoryBarriers, const DependencyFlags dependencyFlags) {
return pipelineBarrier(sourceStages, destinationStages, memoryBarriers, {}, {}, dependencyFlags); return pipelineBarrier(sourceStages, destinationStages, memoryBarriers, {}, {}, dependencyFlags);
} }

35
src/Magnum/Vk/Test/PipelineVkTest.cpp

@ -38,16 +38,18 @@ struct PipelineVkTest: VulkanTester {
explicit PipelineVkTest(); explicit PipelineVkTest();
void pipelineBarrier(); void pipelineBarrier();
void pipelineBarrierGeneral(); void pipelineBarrierExecutionOnly();
void pipelineBarrierBuffer(); void pipelineBarrierGlobalMemory();
void pipelineBarrierImage(); void pipelineBarrierBufferMemory();
void pipelineBarrierImageMemory();
}; };
PipelineVkTest::PipelineVkTest() { PipelineVkTest::PipelineVkTest() {
addTests({&PipelineVkTest::pipelineBarrier, addTests({&PipelineVkTest::pipelineBarrier,
&PipelineVkTest::pipelineBarrierGeneral, &PipelineVkTest::pipelineBarrierExecutionOnly,
&PipelineVkTest::pipelineBarrierBuffer, &PipelineVkTest::pipelineBarrierGlobalMemory,
&PipelineVkTest::pipelineBarrierImage}); &PipelineVkTest::pipelineBarrierBufferMemory,
&PipelineVkTest::pipelineBarrierImageMemory});
} }
void PipelineVkTest::pipelineBarrier() { void PipelineVkTest::pipelineBarrier() {
@ -79,7 +81,22 @@ void PipelineVkTest::pipelineBarrier() {
CORRADE_VERIFY(true); CORRADE_VERIFY(true);
} }
void PipelineVkTest::pipelineBarrierGeneral() { void PipelineVkTest::pipelineBarrierExecutionOnly() {
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)
.end();
/* Does not do anything visible, so just test that it didn't blow up */
CORRADE_VERIFY(true);
}
void PipelineVkTest::pipelineBarrierGlobalMemory() {
CommandPool pool{device(), CommandPoolCreateInfo{ CommandPool pool{device(), CommandPoolCreateInfo{
device().properties().pickQueueFamily(QueueFlag::Graphics)}}; device().properties().pickQueueFamily(QueueFlag::Graphics)}};
@ -96,7 +113,7 @@ void PipelineVkTest::pipelineBarrierGeneral() {
CORRADE_VERIFY(true); CORRADE_VERIFY(true);
} }
void PipelineVkTest::pipelineBarrierBuffer() { void PipelineVkTest::pipelineBarrierBufferMemory() {
CommandPool pool{device(), CommandPoolCreateInfo{ CommandPool pool{device(), CommandPoolCreateInfo{
device().properties().pickQueueFamily(QueueFlag::Graphics)}}; device().properties().pickQueueFamily(QueueFlag::Graphics)}};
@ -115,7 +132,7 @@ void PipelineVkTest::pipelineBarrierBuffer() {
CORRADE_VERIFY(true); CORRADE_VERIFY(true);
} }
void PipelineVkTest::pipelineBarrierImage() { void PipelineVkTest::pipelineBarrierImageMemory() {
CommandPool pool{device(), CommandPoolCreateInfo{ CommandPool pool{device(), CommandPoolCreateInfo{
device().properties().pickQueueFamily(QueueFlag::Graphics)}}; device().properties().pickQueueFamily(QueueFlag::Graphics)}};

Loading…
Cancel
Save