mirror of https://github.com/mosra/magnum.git
10 changed files with 590 additions and 5 deletions
@ -0,0 +1,101 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||
2020, 2021 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "Pipeline.h" |
||||
#include "CommandBuffer.h" |
||||
|
||||
#include <Corrade/Containers/ArrayView.h> |
||||
|
||||
#include "Magnum/Vk/Device.h" |
||||
|
||||
namespace Magnum { namespace Vk { |
||||
|
||||
MemoryBarrier::MemoryBarrier(const Accesses sourceAccesses, const Accesses destinationAccesses): _barrier{} { |
||||
_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; |
||||
_barrier.srcAccessMask = VkAccessFlags(sourceAccesses); |
||||
_barrier.dstAccessMask = VkAccessFlags(destinationAccesses); |
||||
} |
||||
|
||||
MemoryBarrier::MemoryBarrier(NoInitT) noexcept {} |
||||
|
||||
MemoryBarrier::MemoryBarrier(const VkMemoryBarrier& barrier): |
||||
/* Can't use {} with GCC 4.8 here because it tries to initialize the first
|
||||
member instead of doing a copy */ |
||||
_barrier(barrier) {} |
||||
|
||||
BufferMemoryBarrier::BufferMemoryBarrier(const Accesses sourceAccesses, const Accesses destinationAccesses, const VkBuffer buffer, const UnsignedLong offset, const UnsignedLong size): _barrier{} { |
||||
_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; |
||||
_barrier.srcAccessMask = VkAccessFlags(sourceAccesses); |
||||
_barrier.dstAccessMask = VkAccessFlags(destinationAccesses); |
||||
_barrier.buffer = buffer; |
||||
_barrier.offset = offset; |
||||
_barrier.size = size; |
||||
} |
||||
|
||||
BufferMemoryBarrier::BufferMemoryBarrier(NoInitT) noexcept {} |
||||
|
||||
BufferMemoryBarrier::BufferMemoryBarrier(const VkBufferMemoryBarrier& barrier): |
||||
/* Can't use {} with GCC 4.8 here because it tries to initialize the first
|
||||
member instead of doing a copy */ |
||||
_barrier(barrier) {} |
||||
|
||||
ImageMemoryBarrier::ImageMemoryBarrier(const Accesses sourceAccesses, const Accesses destinationAccesses, const ImageLayout oldLayout, const ImageLayout newLayout, const VkImage image, const ImageAspects aspects, const UnsignedInt layerOffset, const UnsignedInt layerCount, const UnsignedInt levelOffset, const UnsignedInt levelCount): _barrier{} { |
||||
_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; |
||||
_barrier.srcAccessMask = VkAccessFlags(sourceAccesses); |
||||
_barrier.dstAccessMask = VkAccessFlags(destinationAccesses); |
||||
_barrier.oldLayout = VkImageLayout(oldLayout); |
||||
_barrier.newLayout = VkImageLayout(newLayout); |
||||
_barrier.image = image; |
||||
_barrier.subresourceRange.aspectMask = VkImageAspectFlags(aspects); |
||||
_barrier.subresourceRange.baseMipLevel = levelOffset; |
||||
_barrier.subresourceRange.levelCount = levelCount; |
||||
_barrier.subresourceRange.baseArrayLayer = layerOffset; |
||||
_barrier.subresourceRange.layerCount = layerCount; |
||||
} |
||||
|
||||
ImageMemoryBarrier::ImageMemoryBarrier(NoInitT) noexcept {} |
||||
|
||||
ImageMemoryBarrier::ImageMemoryBarrier(const VkImageMemoryBarrier& barrier): |
||||
/* Can't use {} with GCC 4.8 here because it tries to initialize the first
|
||||
member instead of doing a copy */ |
||||
_barrier(barrier) {} |
||||
|
||||
CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages, const PipelineStages destinationStages, const Containers::ArrayView<const MemoryBarrier> memoryBarriers, const Containers::ArrayView<const BufferMemoryBarrier> bufferMemoryBarriers, const Containers::ArrayView<const ImageMemoryBarrier> imageMemoryBarriers, const DependencyFlags dependencyFlags) { |
||||
/* Once these grow (VkSampleLocationsInfoEXT?), they will need to be
|
||||
linearized into a separate array first */ |
||||
static_assert( |
||||
sizeof(MemoryBarrier) == sizeof(VkMemoryBarrier) && |
||||
sizeof(BufferMemoryBarrier) == sizeof(VkBufferMemoryBarrier) && |
||||
sizeof(ImageMemoryBarrier) == sizeof(VkImageMemoryBarrier), |
||||
""); |
||||
(**_device).CmdPipelineBarrier(_handle, VkPipelineStageFlags(sourceStages), VkPipelineStageFlags(destinationStages), VkDependencyFlags(dependencyFlags), memoryBarriers.size(), memoryBarriers[0], bufferMemoryBarriers.size(), bufferMemoryBarriers[0], imageMemoryBarriers.size(), imageMemoryBarriers[0]); |
||||
return *this; |
||||
} |
||||
|
||||
CommandBuffer& CommandBuffer::pipelineBarrier(const PipelineStages sourceStages, const PipelineStages destinationStages, const std::initializer_list<MemoryBarrier> memoryBarriers, const std::initializer_list<BufferMemoryBarrier> bufferMemoryBarriers, const std::initializer_list<ImageMemoryBarrier> imageMemoryBarriers, const DependencyFlags dependencyFlags) { |
||||
return pipelineBarrier(sourceStages, destinationStages, Containers::arrayView(memoryBarriers), Containers::arrayView(bufferMemoryBarriers), Containers::arrayView(imageMemoryBarriers), dependencyFlags); |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,155 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||
2020, 2021 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include <new> |
||||
#include <Corrade/TestSuite/Tester.h> |
||||
|
||||
#include "Magnum/Vk/Image.h" |
||||
#include "Magnum/Vk/Pipeline.h" |
||||
|
||||
namespace Magnum { namespace Vk { namespace Test { namespace { |
||||
|
||||
struct PipelineTest: TestSuite::Tester { |
||||
explicit PipelineTest(); |
||||
|
||||
void memoryBarrierConstruct(); |
||||
void memoryBarrierConstructNoInit(); |
||||
void memoryBarrierConstructFromVk(); |
||||
|
||||
void bufferMemoryBarrierConstruct(); |
||||
void bufferMemoryBarrierConstructNoInit(); |
||||
void bufferMemoryBarrierConstructFromVk(); |
||||
|
||||
void imageMemoryBarrierConstruct(); |
||||
void imageMemoryBarrierConstructNoInit(); |
||||
void imageMemoryBarrierConstructFromVk(); |
||||
}; |
||||
|
||||
PipelineTest::PipelineTest() { |
||||
addTests({&PipelineTest::memoryBarrierConstruct, |
||||
&PipelineTest::memoryBarrierConstructNoInit, |
||||
&PipelineTest::memoryBarrierConstructFromVk, |
||||
|
||||
&PipelineTest::bufferMemoryBarrierConstruct, |
||||
&PipelineTest::bufferMemoryBarrierConstructNoInit, |
||||
&PipelineTest::bufferMemoryBarrierConstructFromVk, |
||||
|
||||
&PipelineTest::imageMemoryBarrierConstruct, |
||||
&PipelineTest::imageMemoryBarrierConstructNoInit, |
||||
&PipelineTest::imageMemoryBarrierConstructFromVk}); |
||||
} |
||||
|
||||
void PipelineTest::memoryBarrierConstruct() { |
||||
MemoryBarrier barrier{Access::ColorAttachmentWrite|Access::DepthStencilAttachmentWrite, Access::TransferRead}; |
||||
CORRADE_COMPARE(barrier->srcAccessMask, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT|VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT); |
||||
CORRADE_COMPARE(barrier->dstAccessMask, VK_ACCESS_TRANSFER_READ_BIT); |
||||
} |
||||
|
||||
void PipelineTest::memoryBarrierConstructNoInit() { |
||||
MemoryBarrier barrier{NoInit}; |
||||
barrier->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; |
||||
new(&barrier) MemoryBarrier{NoInit}; |
||||
CORRADE_COMPARE(barrier->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); |
||||
|
||||
CORRADE_VERIFY((std::is_nothrow_constructible<MemoryBarrier, NoInitT>::value)); |
||||
|
||||
/* Implicit construction is not allowed */ |
||||
CORRADE_VERIFY(!(std::is_convertible<NoInitT, MemoryBarrier>::value)); |
||||
} |
||||
|
||||
void PipelineTest::memoryBarrierConstructFromVk() { |
||||
VkMemoryBarrier vkBarrier; |
||||
vkBarrier.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; |
||||
|
||||
MemoryBarrier barrier{vkBarrier}; |
||||
CORRADE_COMPARE(barrier->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); |
||||
} |
||||
|
||||
void PipelineTest::bufferMemoryBarrierConstruct() { |
||||
BufferMemoryBarrier barrier{Access::ColorAttachmentWrite|Access::DepthStencilAttachmentWrite, Access::TransferRead, reinterpret_cast<VkBuffer>(0xdead), 3, 5}; |
||||
CORRADE_COMPARE(barrier->srcAccessMask, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT|VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT); |
||||
CORRADE_COMPARE(barrier->dstAccessMask, VK_ACCESS_TRANSFER_READ_BIT); |
||||
CORRADE_COMPARE(barrier->buffer, reinterpret_cast<VkBuffer>(0xdead)); |
||||
CORRADE_COMPARE(barrier->offset, 3); |
||||
CORRADE_COMPARE(barrier->size, 5); |
||||
} |
||||
|
||||
void PipelineTest::bufferMemoryBarrierConstructNoInit() { |
||||
BufferMemoryBarrier barrier{NoInit}; |
||||
barrier->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; |
||||
new(&barrier) BufferMemoryBarrier{NoInit}; |
||||
CORRADE_COMPARE(barrier->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); |
||||
|
||||
CORRADE_VERIFY((std::is_nothrow_constructible<BufferMemoryBarrier, NoInitT>::value)); |
||||
|
||||
/* Implicit construction is not allowed */ |
||||
CORRADE_VERIFY(!(std::is_convertible<NoInitT, BufferMemoryBarrier>::value)); |
||||
} |
||||
|
||||
void PipelineTest::bufferMemoryBarrierConstructFromVk() { |
||||
VkBufferMemoryBarrier vkBarrier; |
||||
vkBarrier.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; |
||||
|
||||
BufferMemoryBarrier barrier{vkBarrier}; |
||||
CORRADE_COMPARE(barrier->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); |
||||
} |
||||
|
||||
void PipelineTest::imageMemoryBarrierConstruct() { |
||||
ImageMemoryBarrier barrier{Access::ColorAttachmentWrite|Access::DepthStencilAttachmentWrite, Access::TransferRead, ImageLayout::Preinitialized, ImageLayout::TransferSource, reinterpret_cast<VkImage>(0xdead), ImageAspect::Color|ImageAspect::Depth, 3, 5, 7, 9}; |
||||
CORRADE_COMPARE(barrier->srcAccessMask, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT|VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT); |
||||
CORRADE_COMPARE(barrier->dstAccessMask, VK_ACCESS_TRANSFER_READ_BIT); |
||||
CORRADE_COMPARE(barrier->oldLayout, VK_IMAGE_LAYOUT_PREINITIALIZED); |
||||
CORRADE_COMPARE(barrier->newLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); |
||||
CORRADE_COMPARE(barrier->image, reinterpret_cast<VkImage>(0xdead)); |
||||
CORRADE_COMPARE(barrier->subresourceRange.aspectMask, VK_IMAGE_ASPECT_COLOR_BIT|VK_IMAGE_ASPECT_DEPTH_BIT); |
||||
CORRADE_COMPARE(barrier->subresourceRange.baseMipLevel, 7); |
||||
CORRADE_COMPARE(barrier->subresourceRange.levelCount, 9); |
||||
CORRADE_COMPARE(barrier->subresourceRange.baseArrayLayer, 3); |
||||
CORRADE_COMPARE(barrier->subresourceRange.layerCount, 5); |
||||
} |
||||
|
||||
void PipelineTest::imageMemoryBarrierConstructNoInit() { |
||||
ImageMemoryBarrier barrier{NoInit}; |
||||
barrier->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; |
||||
new(&barrier) ImageMemoryBarrier{NoInit}; |
||||
CORRADE_COMPARE(barrier->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); |
||||
|
||||
CORRADE_VERIFY((std::is_nothrow_constructible<ImageMemoryBarrier, NoInitT>::value)); |
||||
|
||||
/* Implicit construction is not allowed */ |
||||
CORRADE_VERIFY(!(std::is_convertible<NoInitT, ImageMemoryBarrier>::value)); |
||||
} |
||||
|
||||
void PipelineTest::imageMemoryBarrierConstructFromVk() { |
||||
VkImageMemoryBarrier vkBarrier; |
||||
vkBarrier.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; |
||||
|
||||
ImageMemoryBarrier barrier{vkBarrier}; |
||||
CORRADE_COMPARE(barrier->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); |
||||
} |
||||
|
||||
}}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::Vk::Test::PipelineTest) |
||||
@ -0,0 +1,78 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||
2020, 2021 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "Magnum/Vk/BufferCreateInfo.h" |
||||
#include "Magnum/Vk/CommandBuffer.h" |
||||
#include "Magnum/Vk/CommandPoolCreateInfo.h" |
||||
#include "Magnum/Vk/DeviceProperties.h" |
||||
#include "Magnum/Vk/ImageCreateInfo.h" |
||||
#include "Magnum/Vk/Pipeline.h" |
||||
#include "Magnum/Vk/PixelFormat.h" |
||||
#include "Magnum/Vk/VulkanTester.h" |
||||
|
||||
namespace Magnum { namespace Vk { namespace Test { namespace { |
||||
|
||||
struct PipelineVkTest: VulkanTester { |
||||
explicit PipelineVkTest(); |
||||
|
||||
void pipelineBarrier(); |
||||
}; |
||||
|
||||
PipelineVkTest::PipelineVkTest() { |
||||
addTests({&PipelineVkTest::pipelineBarrier}); |
||||
} |
||||
|
||||
void PipelineVkTest::pipelineBarrier() { |
||||
CommandPool pool{device(), CommandPoolCreateInfo{ |
||||
device().properties().pickQueueFamily(QueueFlag::Graphics)}}; |
||||
|
||||
Buffer buffer{device(), BufferCreateInfo{ |
||||
BufferUsage::TransferDestination|BufferUsage::VertexBuffer, 16 |
||||
}, MemoryFlag::DeviceLocal}; |
||||
Image image{device(), ImageCreateInfo2D{ |
||||
ImageUsage::TransferDestination|ImageUsage::Sampled, |
||||
PixelFormat::RGBA8Unorm, {4, 4}, 1 |
||||
}, MemoryFlag::DeviceLocal}; |
||||
|
||||
pool.allocate() |
||||
.begin() |
||||
.pipelineBarrier(PipelineStage::Transfer, PipelineStage::Host|PipelineStage::VertexInput|PipelineStage::FragmentShader, { |
||||
{Access::TransferWrite, Access::HostRead} |
||||
}, { |
||||
{Access::TransferWrite, Access::VertexAttributeRead, buffer} |
||||
}, { |
||||
{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) |
||||
Loading…
Reference in new issue