From 65346cdb5a7d7a67985c4eef65cbc2aa65d1b16f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 27 Jan 2021 22:04:19 +0100 Subject: [PATCH] Vk: an extremely minimal PipelineLayout wrapper. As in, does absolutely nothing. --- doc/vulkan-mapping.dox | 6 +- src/Magnum/Vk/CMakeLists.txt | 3 + src/Magnum/Vk/PipelineLayout.cpp | 83 ++++++++++++ src/Magnum/Vk/PipelineLayout.h | 134 ++++++++++++++++++++ src/Magnum/Vk/PipelineLayoutCreateInfo.h | 96 ++++++++++++++ src/Magnum/Vk/Test/CMakeLists.txt | 4 + src/Magnum/Vk/Test/PipelineLayoutTest.cpp | 96 ++++++++++++++ src/Magnum/Vk/Test/PipelineLayoutVkTest.cpp | 98 ++++++++++++++ src/Magnum/Vk/Vk.h | 2 + 9 files changed, 519 insertions(+), 3 deletions(-) create mode 100644 src/Magnum/Vk/PipelineLayout.cpp create mode 100644 src/Magnum/Vk/PipelineLayout.h create mode 100644 src/Magnum/Vk/PipelineLayoutCreateInfo.h create mode 100644 src/Magnum/Vk/Test/PipelineLayoutTest.cpp create mode 100644 src/Magnum/Vk/Test/PipelineLayoutVkTest.cpp diff --git a/doc/vulkan-mapping.dox b/doc/vulkan-mapping.dox index b2f7937cf..87caad62d 100644 --- a/doc/vulkan-mapping.dox +++ b/doc/vulkan-mapping.dox @@ -71,7 +71,7 @@ Vulkan handle | Matching API @type_vk{Instance} | @ref Instance @type_vk{PhysicalDevice} | @ref DeviceProperties @type_vk{Pipeline} | | -@type_vk{PipelineLayout} | | +@type_vk{PipelineLayout} | @ref PipelineLayout @type_vk{QueryPool} | | @type_vk{Queue} | @ref Queue @type_vk{RenderPass} | @ref RenderPass @@ -202,7 +202,7 @@ Vulkan function | Matching API @fn_vk{CreateInstance}, \n @fn_vk{DestroyInstance} | @ref Instance constructor and destructor @fn_vk{CreatePipeline}, \n @fn_vk{DestroyPipeline} | | @fn_vk{CreatePipelineCache}, \n @fn_vk{DestroyPipelineCache} | | -@fn_vk{CreatePipelineLayout}, \n @fn_vk{DestroyPipelineLayout} | | +@fn_vk{CreatePipelineLayout}, \n @fn_vk{DestroyPipelineLayout} | @ref PipelineLayout constructor and destructor @fn_vk{CreateQueryPool}, \n @fn_vk{DestroyQueryPool} | | @fn_vk{CreateRayTracingPipelinesKHR} @m_class{m-label m-flat m-warning} **KHR** | | @fn_vk{CreateRenderPass}, \n @fn_vk{CreateRenderPass2} @m_class{m-label m-flat m-success} **KHR, 1.2**, \n @fn_vk{DestroyRenderPass} | @ref RenderPass constructor and destructor @@ -660,7 +660,7 @@ Vulkan structure | Matching API @type_vk{PipelineDepthStencilStateCreateInfo} | | @type_vk{PipelineDynamicStateCreateInfo} | | @type_vk{PipelineInputAssemblyStateCreateInfo} | @ref MeshLayout -@type_vk{PipelineLayoutCreateInfo} | | +@type_vk{PipelineLayoutCreateInfo} | @ref PipelineLayoutCreateInfo @type_vk{PipelineLibraryCreateInfoKHR} @m_class{m-label m-flat m-warning} **KHR** | | @type_vk{PipelineMultisampleStateCreateInfo} | | @type_vk{PipelineRasterizationStateCreateInfo} | | diff --git a/src/Magnum/Vk/CMakeLists.txt b/src/Magnum/Vk/CMakeLists.txt index 2445e3d81..4970090e3 100644 --- a/src/Magnum/Vk/CMakeLists.txt +++ b/src/Magnum/Vk/CMakeLists.txt @@ -34,6 +34,7 @@ set(MagnumVk_SRCS Framebuffer.cpp Handle.cpp Pipeline.cpp + PipelineLayout.cpp Queue.cpp Result.cpp Shader.cpp @@ -92,6 +93,8 @@ set(MagnumVk_HEADERS MemoryAllocateInfo.h MeshLayout.h Pipeline.h + PipelineLayout.h + PipelineLayoutCreateInfo.h PixelFormat.h Queue.h RenderPass.h diff --git a/src/Magnum/Vk/PipelineLayout.cpp b/src/Magnum/Vk/PipelineLayout.cpp new file mode 100644 index 000000000..7c51015e1 --- /dev/null +++ b/src/Magnum/Vk/PipelineLayout.cpp @@ -0,0 +1,83 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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 "PipelineLayout.h" +#include "PipelineLayoutCreateInfo.h" + +#include "Magnum/Vk/Assert.h" +#include "Magnum/Vk/Device.h" +#include "Magnum/Vk/Result.h" + +namespace Magnum { namespace Vk { + +PipelineLayoutCreateInfo::PipelineLayoutCreateInfo(): _info{} { + _info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; +} + +PipelineLayoutCreateInfo::PipelineLayoutCreateInfo(NoInitT) noexcept {} + +PipelineLayoutCreateInfo::PipelineLayoutCreateInfo(const VkPipelineLayoutCreateInfo& info): + /* Can't use {} with GCC 4.8 here because it tries to initialize the first + member instead of doing a copy */ + _info(info) {} + +PipelineLayout PipelineLayout::wrap(Device& device, const VkPipelineLayout handle, const HandleFlags flags) { + PipelineLayout out{NoCreate}; + out._device = &device; + out._handle = handle; + out._flags = flags; + return out; +} + +PipelineLayout::PipelineLayout(Device& device, const PipelineLayoutCreateInfo& info): _device{&device}, _flags{HandleFlag::DestroyOnDestruction} { + MAGNUM_VK_INTERNAL_ASSERT_SUCCESS(device->CreatePipelineLayout(device, info, nullptr, &_handle)); +} + +PipelineLayout::PipelineLayout(NoCreateT): _device{}, _handle{} {} + +PipelineLayout::PipelineLayout(PipelineLayout&& other) noexcept: _device{other._device}, _handle{other._handle}, _flags{other._flags} { + other._handle = {}; +} + +PipelineLayout::~PipelineLayout() { + if(_handle && (_flags & HandleFlag::DestroyOnDestruction)) + (**_device).DestroyPipelineLayout(*_device, _handle, nullptr); +} + +PipelineLayout& PipelineLayout::operator=(PipelineLayout&& other) noexcept { + using std::swap; + swap(other._device, _device); + swap(other._handle, _handle); + swap(other._flags, _flags); + return *this; +} + +VkPipelineLayout PipelineLayout::release() { + const VkPipelineLayout handle = _handle; + _handle = {}; + return handle; +} + +}} diff --git a/src/Magnum/Vk/PipelineLayout.h b/src/Magnum/Vk/PipelineLayout.h new file mode 100644 index 000000000..ed3ba2788 --- /dev/null +++ b/src/Magnum/Vk/PipelineLayout.h @@ -0,0 +1,134 @@ +#ifndef Magnum_Vk_PipelineLayout_h +#define Magnum_Vk_PipelineLayout_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class @ref Magnum::Vk::PipelineLayout + * @m_since_latest + */ + +#include "Magnum/Magnum.h" +#include "Magnum/Tags.h" +#include "Magnum/Vk/Handle.h" +#include "Magnum/Vk/Vk.h" +#include "Magnum/Vk/Vulkan.h" +#include "Magnum/Vk/visibility.h" + +namespace Magnum { namespace Vk { + +/** +@brief Pipeline layout +@m_since_latest + +Wraps a @type_vk_keyword{PipelineLayout}. +*/ +class MAGNUM_VK_EXPORT PipelineLayout { + public: + /** + * @brief Wrap existing Vulkan handle + * @param device Vulkan device the pipeline layout is + * created on + * @param handle The @type_vk{PipelineLayout} handle + * @param flags Handle flags + * + * The @p handle is expected to be originating from @p device. Unlike + * a pipeline layout created using a constructor, the Vulkan pipeline + * layout is by default not deleted on destruction, use @p flags for + * different behavior. + * @see @ref release() + */ + static PipelineLayout wrap(Device& device, VkPipelineLayout handle, HandleFlags flags = {}); + + /** + * @brief Constructor + * @param device Vulkan device to create the pipeline layout on + * @param info Pipeline layout creation info + * + * @see @fn_vk_keyword{CreatePipelineLayout} + */ + explicit PipelineLayout(Device& device, const PipelineLayoutCreateInfo& info); + + /** + * @brief Construct without creating the pipeline layout + * + * The constructed instance is equivalent to moved-from state. Useful + * in cases where you will overwrite the instance later anyway. Move + * another object over it to make it useful. + */ + explicit PipelineLayout(NoCreateT); + + /** @brief Copying is not allowed */ + PipelineLayout(const PipelineLayout&) = delete; + + /** @brief Move constructor */ + PipelineLayout(PipelineLayout&& other) noexcept; + + /** + * @brief Destructor + * + * Destroys associated @type_vk{PipelineLayout} handle, unless the + * instance was created using @ref wrap() without + * @ref HandleFlag::DestroyOnDestruction specified. + * @see @fn_vk_keyword{DestroyPipelineLayout}, @ref release() + */ + ~PipelineLayout(); + + /** @brief Copying is not allowed */ + PipelineLayout& operator=(const PipelineLayout&) = delete; + + /** @brief Move assignment */ + PipelineLayout& operator=(PipelineLayout&& other) noexcept; + + /** @brief Underlying @type_vk{PipelineLayout} handle */ + VkPipelineLayout handle() { return _handle; } + /** @overload */ + operator VkPipelineLayout() { return _handle; } + + /** @brief Handle flags */ + HandleFlags handleFlags() const { return _flags; } + + /** + * @brief Release the underlying Vulkan pipeline layout + * + * Releases ownership of the Vulkan pipeline layout and returns its + * handle so @fn_vk{DestroyPipelineLayout} is not called on + * destruction. The internal state is then equivalent to moved-from + * state. + * @see @ref wrap() + */ + VkPipelineLayout release(); + + private: + /* Can't be a reference because of the NoCreate constructor */ + Device* _device; + + VkPipelineLayout _handle; + HandleFlags _flags; +}; + +}} + +#endif diff --git a/src/Magnum/Vk/PipelineLayoutCreateInfo.h b/src/Magnum/Vk/PipelineLayoutCreateInfo.h new file mode 100644 index 000000000..f6067d0a3 --- /dev/null +++ b/src/Magnum/Vk/PipelineLayoutCreateInfo.h @@ -0,0 +1,96 @@ +#ifndef Magnum_Vk_PipelineLayoutCreateInfo_h +#define Magnum_Vk_PipelineLayoutCreateInfo_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class @ref Magnum::Vk::PipelineLayoutCreateInfo + * @m_since_latest + */ + +#include "Magnum/Tags.h" +#include "Magnum/Vk/Vk.h" +#include "Magnum/Vk/Vulkan.h" +#include "Magnum/Vk/visibility.h" + +namespace Magnum { namespace Vk { + +/** +@brief Pipeline layout creation info +@m_since_latest + +Wraps a @type_vk_keyword{PipelineLayoutCreateInfo}. +*/ +class MAGNUM_VK_EXPORT PipelineLayoutCreateInfo { + public: + /** + * @brief Constructor + * + * The following @type_vk{PipelineLayoutCreateInfo} fields are + * pre-filled in addition to `sType`, everything else is zero-filled: + * + * - (none) + */ + explicit PipelineLayoutCreateInfo(); + + /** + * @brief Construct without initializing the contents + * + * Note that not even the `sType` field is set --- the structure has to + * be fully initialized afterwards in order to be usable. + */ + explicit PipelineLayoutCreateInfo(NoInitT) noexcept; + + /** + * @brief Construct from existing data + * + * Copies the existing values verbatim, pointers are kept unchanged + * without taking over the ownership. Modifying the newly created + * instance will not modify the original data nor the pointed-to data. + */ + explicit PipelineLayoutCreateInfo(const VkPipelineLayoutCreateInfo& info); + + /** @brief Underlying @type_vk{PipelineLayoutCreateInfo} structure */ + VkPipelineLayoutCreateInfo& operator*() { return _info; } + /** @overload */ + const VkPipelineLayoutCreateInfo& operator*() const { return _info; } + /** @overload */ + VkPipelineLayoutCreateInfo* operator->() { return &_info; } + /** @overload */ + const VkPipelineLayoutCreateInfo* operator->() const { return &_info; } + /** @overload */ + operator const VkPipelineLayoutCreateInfo*() const { return &_info; } + + private: + VkPipelineLayoutCreateInfo _info; +}; + +}} + +/* Make the definition complete -- it doesn't make sense to have a CreateInfo + without the corresponding object anyway. */ +#include "Magnum/Vk/PipelineLayout.h" + +#endif diff --git a/src/Magnum/Vk/Test/CMakeLists.txt b/src/Magnum/Vk/Test/CMakeLists.txt index 0e158a378..a74de4e0a 100644 --- a/src/Magnum/Vk/Test/CMakeLists.txt +++ b/src/Magnum/Vk/Test/CMakeLists.txt @@ -44,6 +44,7 @@ corrade_add_test(VkLayerPropertiesTest LayerPropertiesTest.cpp LIBRARIES MagnumV corrade_add_test(VkMemoryTest MemoryTest.cpp LIBRARIES MagnumVkTestLib) corrade_add_test(VkMeshLayoutTest MeshLayoutTest.cpp LIBRARIES MagnumVkTestLib) corrade_add_test(VkPipelineTest PipelineTest.cpp LIBRARIES MagnumVk) +corrade_add_test(VkPipelineLayoutTest PipelineLayoutTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkPixelFormatTest PixelFormatTest.cpp LIBRARIES MagnumVkTestLib) corrade_add_test(VkQueueTest QueueTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkResultTest ResultTest.cpp LIBRARIES MagnumVk) @@ -140,6 +141,7 @@ set_target_properties( VkMemoryTest VkMeshLayoutTest VkPipelineTest + VkPipelineLayoutTest VkPixelFormatTest VkQueueTest VkResultTest @@ -174,6 +176,7 @@ if(BUILD_VK_TESTS) corrade_add_test(VkInstanceVkTest InstanceVkTest.cpp LIBRARIES MagnumVkTestLib) corrade_add_test(VkMemoryVkTest MemoryVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester) corrade_add_test(VkPipelineVkTest PipelineVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester) + corrade_add_test(VkPipelineLayoutVkTest PipelineLayoutVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester) corrade_add_test(VkQueueVkTest QueueVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester) corrade_add_test(VkRenderPassVkTest RenderPassVkTest.cpp LIBRARIES MagnumVkTestLib MagnumVulkanTester) corrade_add_test(VkShaderVkTest ShaderVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester) @@ -195,6 +198,7 @@ if(BUILD_VK_TESTS) VkInstanceVkTest VkMemoryVkTest VkPipelineVkTest + VkPipelineLayoutVkTest VkQueueVkTest VkRenderPassVkTest VkShaderVkTest diff --git a/src/Magnum/Vk/Test/PipelineLayoutTest.cpp b/src/Magnum/Vk/Test/PipelineLayoutTest.cpp new file mode 100644 index 000000000..bca890674 --- /dev/null +++ b/src/Magnum/Vk/Test/PipelineLayoutTest.cpp @@ -0,0 +1,96 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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 +#include + +#include "Magnum/Vk/PipelineLayoutCreateInfo.h" + +namespace Magnum { namespace Vk { namespace Test { namespace { + +struct PipelineLayoutTest: TestSuite::Tester { + explicit PipelineLayoutTest(); + + void createInfoConstruct(); + void createInfoConstructNoInit(); + void createInfoConstructFromVk(); + + void constructNoCreate(); + void constructCopy(); +}; + +PipelineLayoutTest::PipelineLayoutTest() { + addTests({&PipelineLayoutTest::createInfoConstruct, + &PipelineLayoutTest::createInfoConstructNoInit, + &PipelineLayoutTest::createInfoConstructFromVk, + + &PipelineLayoutTest::constructNoCreate, + &PipelineLayoutTest::constructCopy}); +} + +void PipelineLayoutTest::createInfoConstruct() { + PipelineLayoutCreateInfo info; + /** @todo expand once there's actually something */ + CORRADE_COMPARE(info->flags, 0); +} + +void PipelineLayoutTest::createInfoConstructNoInit() { + PipelineLayoutCreateInfo info{NoInit}; + info->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; + new(&info) PipelineLayoutCreateInfo{NoInit}; + CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); + + CORRADE_VERIFY((std::is_nothrow_constructible::value)); + + /* Implicit construction is not allowed */ + CORRADE_VERIFY(!(std::is_convertible::value)); +} + +void PipelineLayoutTest::createInfoConstructFromVk() { + VkPipelineLayoutCreateInfo vkInfo; + vkInfo.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; + + PipelineLayoutCreateInfo info{vkInfo}; + CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); +} + +void PipelineLayoutTest::constructNoCreate() { + { + PipelineLayout layout{NoCreate}; + CORRADE_VERIFY(!layout.handle()); + } + + /* Implicit construction is not allowed */ + CORRADE_VERIFY(!(std::is_convertible::value)); +} + +void PipelineLayoutTest::constructCopy() { + CORRADE_VERIFY(!std::is_copy_constructible{}); + CORRADE_VERIFY(!std::is_copy_assignable{}); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Vk::Test::PipelineLayoutTest) diff --git a/src/Magnum/Vk/Test/PipelineLayoutVkTest.cpp b/src/Magnum/Vk/Test/PipelineLayoutVkTest.cpp new file mode 100644 index 000000000..0c5b92a79 --- /dev/null +++ b/src/Magnum/Vk/Test/PipelineLayoutVkTest.cpp @@ -0,0 +1,98 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021 Vladimír Vondruš + + 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 + +#include "Magnum/Vk/PipelineLayoutCreateInfo.h" +#include "Magnum/Vk/Result.h" +#include "Magnum/Vk/VulkanTester.h" + +namespace Magnum { namespace Vk { namespace Test { namespace { + +struct PipelineLayoutVkTest: VulkanTester { + explicit PipelineLayoutVkTest(); + + void construct(); + void constructMove(); + + void wrap(); +}; + +PipelineLayoutVkTest::PipelineLayoutVkTest() { + addTests({&PipelineLayoutVkTest::construct, + &PipelineLayoutVkTest::constructMove, + + &PipelineLayoutVkTest::wrap}); +} + +void PipelineLayoutVkTest::construct() { + { + PipelineLayout layout{device(), PipelineLayoutCreateInfo{}}; + CORRADE_VERIFY(layout.handle()); + CORRADE_COMPARE(layout.handleFlags(), HandleFlag::DestroyOnDestruction); + } + + /* Shouldn't crash or anything */ + CORRADE_VERIFY(true); +} + +void PipelineLayoutVkTest::constructMove() { + PipelineLayout a{device(), PipelineLayoutCreateInfo{}}; + VkPipelineLayout handle = a.handle(); + + PipelineLayout b = std::move(a); + CORRADE_VERIFY(!a.handle()); + CORRADE_COMPARE(b.handle(), handle); + CORRADE_COMPARE(b.handleFlags(), HandleFlag::DestroyOnDestruction); + + PipelineLayout c{NoCreate}; + c = std::move(b); + CORRADE_VERIFY(!b.handle()); + CORRADE_COMPARE(b.handleFlags(), HandleFlags{}); + CORRADE_COMPARE(c.handle(), handle); + CORRADE_COMPARE(c.handleFlags(), HandleFlag::DestroyOnDestruction); + + CORRADE_VERIFY(std::is_nothrow_move_constructible::value); + CORRADE_VERIFY(std::is_nothrow_move_assignable::value); +} + +void PipelineLayoutVkTest::wrap() { + VkPipelineLayout layout{}; + CORRADE_COMPARE(Result(device()->CreatePipelineLayout(device(), + PipelineLayoutCreateInfo{}, + nullptr, &layout)), Result::Success); + + auto wrapped = PipelineLayout::wrap(device(), layout, HandleFlag::DestroyOnDestruction); + CORRADE_COMPARE(wrapped.handle(), layout); + + /* Release the handle again, destroy by hand */ + CORRADE_COMPARE(wrapped.release(), layout); + CORRADE_VERIFY(!wrapped.handle()); + device()->DestroyPipelineLayout(device(), layout, nullptr); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Vk::Test::PipelineLayoutVkTest) diff --git a/src/Magnum/Vk/Vk.h b/src/Magnum/Vk/Vk.h index 5657b3b34..eb339a740 100644 --- a/src/Magnum/Vk/Vk.h +++ b/src/Magnum/Vk/Vk.h @@ -96,6 +96,8 @@ enum class MemoryHeapFlag: UnsignedInt; typedef Containers::EnumSet MemoryHeapFlags; class MeshLayout; enum class MeshPrimitive: Int; +class PipelineLayout; +class PipelineLayoutCreateInfo; enum class PipelineStage: UnsignedInt; typedef Containers::EnumSet PipelineStages; enum class PixelFormat: Int;