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