diff --git a/doc/snippets/MagnumVk.cpp b/doc/snippets/MagnumVk.cpp index bb157c1eb..41a88a7a4 100644 --- a/doc/snippets/MagnumVk.cpp +++ b/doc/snippets/MagnumVk.cpp @@ -38,6 +38,7 @@ #include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/Extensions.h" #include "Magnum/Vk/ExtensionProperties.h" +#include "Magnum/Vk/FenceCreateInfo.h" #include "Magnum/Vk/FramebufferCreateInfo.h" #include "Magnum/Vk/InstanceCreateInfo.h" #include "Magnum/Vk/Integration.h" @@ -292,6 +293,18 @@ if(device.isExtensionEnabled()) { /* [Device-isExtensionEnabled] */ } +{ +Vk::Device device{DOXYGEN_IGNORE(NoCreate)}; +/* The include should be a no-op here since it was already included above */ +/* [Fence-creation] */ +#include + +DOXYGEN_IGNORE() + +Vk::Fence fence{device, Vk::FenceCreateInfo{Vk::FenceCreateInfo::Flag::Signaled}}; +/* [Fence-creation] */ +} + { Vk::Device device{DOXYGEN_IGNORE(NoCreate)}; Vector2i size; diff --git a/doc/vulkan-mapping.dox b/doc/vulkan-mapping.dox index 86167bbdf..7fade0567 100644 --- a/doc/vulkan-mapping.dox +++ b/doc/vulkan-mapping.dox @@ -149,7 +149,7 @@ Vulkan function | Matching API @fn_vk{CreateDescriptorUpdateTemplate} @m_class{m-label m-flat m-success} **KHR, 1.1**, \n @fn_vk{DestroyDescriptorUpdateTemplate} @m_class{m-label m-flat m-success} **KHR, 1.1** | | @fn_vk{CreateDevice}, \n @fn_vk{DestroyDevice} | @ref Device constructor and destructor @fn_vk{CreateEvent}, \n @fn_vk{DestroyEvent} | | -@fn_vk{CreateFence}, \n @fn_vk{DestroyFence} | | +@fn_vk{CreateFence}, \n @fn_vk{DestroyFence} | @ref Fence constructor and destructor @fn_vk{CreateFramebuffer}, \n @fn_vk{DestroyFramebuffer} | @ref Framebuffer constructor and destructor @fn_vk{CreateImage}, \n @fn_vk{DestroyImage} | @ref Image constructor and destructor @fn_vk{CreateImageView}, \n @fn_vk{DestroyImageView} | @ref ImageView constructor and destructor @@ -467,7 +467,7 @@ Vulkan structure | Matching API Vulkan structure | Matching API --------------------------------------- | ------------ -@type_vk{FenceCreateInfo} | | +@type_vk{FenceCreateInfo} | @ref FenceCreateInfo @type_vk{FormatProperties}, \n @type_vk{FormatProperties2} @m_class{m-label m-flat m-success} **KHR, 1.1** | | @type_vk{FramebufferAttachmentsCreateInfo} @m_class{m-label m-flat m-success} **KHR, 1.2** | | @type_vk{FramebufferAttachmentImageInfo} @m_class{m-label m-flat m-success} **KHR, 1.2** | | diff --git a/src/Magnum/Vk/CMakeLists.txt b/src/Magnum/Vk/CMakeLists.txt index 3fc9551f8..f5e55f7ec 100644 --- a/src/Magnum/Vk/CMakeLists.txt +++ b/src/Magnum/Vk/CMakeLists.txt @@ -30,6 +30,7 @@ set(MagnumVk_SRCS CommandBuffer.cpp CommandPool.cpp Extensions.cpp + Fence.cpp Framebuffer.cpp Handle.cpp Instance.cpp @@ -68,6 +69,8 @@ set(MagnumVk_HEADERS Enums.h Extensions.h ExtensionProperties.h + Fence.h + FenceCreateInfo.h Framebuffer.h FramebufferCreateInfo.h Handle.h diff --git a/src/Magnum/Vk/Fence.cpp b/src/Magnum/Vk/Fence.cpp new file mode 100644 index 000000000..d5a844173 --- /dev/null +++ b/src/Magnum/Vk/Fence.cpp @@ -0,0 +1,85 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 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 "Fence.h" +#include "FenceCreateInfo.h" + +#include "Magnum/Vk/Assert.h" +#include "Magnum/Vk/Device.h" + +namespace Magnum { namespace Vk { + +FenceCreateInfo::FenceCreateInfo(const Flags flags): _info{} { + _info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + _info.flags = VkFenceCreateFlags(flags); +} + +FenceCreateInfo::FenceCreateInfo(NoInitT) noexcept {} + +FenceCreateInfo::FenceCreateInfo(const VkFenceCreateInfo& info): + /* Can't use {} with GCC 4.8 here because it tries to initialize the first + member instead of doing a copy */ + _info(info) {} + +Fence Fence::wrap(Device& device, const VkFence handle, const HandleFlags flags) { + Fence out{NoCreate}; + out._device = &device; + out._handle = handle; + out._flags = flags; + return out; +} + +Fence::Fence(Device& device, const FenceCreateInfo& info): _device{&device}, _flags{HandleFlag::DestroyOnDestruction} { + MAGNUM_VK_INTERNAL_ASSERT_SUCCESS(device->CreateFence(device, info, nullptr, &_handle)); +} + +Fence::Fence(Device& device): Fence{device, FenceCreateInfo{}} {} + +Fence::Fence(NoCreateT): _device{}, _handle{} {} + +Fence::Fence(Fence&& other) noexcept: _device{other._device}, _handle{other._handle}, _flags{other._flags} { + other._handle = {}; +} + +Fence::~Fence() { + if(_handle && (_flags & HandleFlag::DestroyOnDestruction)) + (**_device).DestroyFence(*_device, _handle, nullptr); +} + +Fence& Fence::operator=(Fence&& other) noexcept { + using std::swap; + swap(other._device, _device); + swap(other._handle, _handle); + swap(other._flags, _flags); + return *this; +} + +VkFence Fence::release() { + const VkFence handle = _handle; + _handle = {}; + return handle; +} + +}} diff --git a/src/Magnum/Vk/Fence.h b/src/Magnum/Vk/Fence.h new file mode 100644 index 000000000..324acbf46 --- /dev/null +++ b/src/Magnum/Vk/Fence.h @@ -0,0 +1,145 @@ +#ifndef Magnum_Vk_Fence_h +#define Magnum_Vk_Fence_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 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::Fence + * @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 Fence +@m_since_latest + +Wraps a @type_vk_keyword{Fence}. + +@section Vk-Fence-creation Fence creation + +A fence doesn't need any extra parameters for construction and can be +constructed directly using @ref Fence(Device&, const FenceCreateInfo&), leaving +the @p info parameter at its default. If you want to pass additional parameters +to it, include the @ref FenceCreateInfo class as usual: + +@snippet MagnumVk.cpp Fence-creation +*/ +class MAGNUM_VK_EXPORT Fence { + public: + /** + * @brief Wrap existing Vulkan handle + * @param device Vulkan device the fence is created on + * @param handle The @type_vk{Fence} handle + * @param flags Handle flags + * + * The @p handle is expected to be originating from @p device. Unlike + * a fence created using a constructor, the Vulkan fence is by default + * not deleted on destruction, use @p flags for different behavior. + * @see @ref release() + */ + static Fence wrap(Device& device, VkFence handle, HandleFlags flags = {}); + + /** + * @brief Constructor + * @param device Vulkan device to create the fence on + * @param info Fence creation info + * + * @see @fn_vk_keyword{CreateFence} + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + explicit Fence(Device& device, const FenceCreateInfo& info = FenceCreateInfo{}); + #else + explicit Fence(Device& device, const FenceCreateInfo& info); + explicit Fence(Device& device); + #endif + + /** + * @brief Construct without creating the fence + * + * 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 Fence(NoCreateT); + + /** @brief Copying is not allowed */ + Fence(const Fence&) = delete; + + /** @brief Move constructor */ + Fence(Fence&& other) noexcept; + + /** + * @brief Destructor + * + * Destroys associated @type_vk{Fence} handle, unless the instance was + * created using @ref wrap() without + * @ref HandleFlag::DestroyOnDestruction specified. + * @see @fn_vk_keyword{DestroyFence}, @ref release() + */ + ~Fence(); + + /** @brief Copying is not allowed */ + Fence& operator=(const Fence&) = delete; + + /** @brief Move assignment */ + Fence& operator=(Fence&& other) noexcept; + + /** @brief Underlying @type_vk{Fence} handle */ + VkFence handle() { return _handle; } + /** @overload */ + operator VkFence() { return _handle; } + + /** @brief Handle flags */ + HandleFlags handleFlags() const { return _flags; } + + /** + * @brief Release the underlying Vulkan fence + * + * Releases ownership of the Vulkan fence and returns its handle so + * @fn_vk{DestroyFence} is not called on destruction. The internal + * state is then equivalent to moved-from state. + * @see @ref wrap() + */ + VkFence release(); + + private: + /* Can't be a reference because of the NoCreate constructor */ + Device* _device; + + VkFence _handle; + HandleFlags _flags; +}; + +}} + +#endif diff --git a/src/Magnum/Vk/FenceCreateInfo.h b/src/Magnum/Vk/FenceCreateInfo.h new file mode 100644 index 000000000..2e3d55df6 --- /dev/null +++ b/src/Magnum/Vk/FenceCreateInfo.h @@ -0,0 +1,127 @@ +#ifndef Magnum_Vk_FenceCreateInfo_h +#define Magnum_Vk_FenceCreateInfo_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 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::FenceCreateInfo + * @m_since_latest + */ + +#include +#include + +#include "Magnum/Magnum.h" +#include "Magnum/Tags.h" +#include "Magnum/Vk/visibility.h" +#include "Magnum/Vk/Vk.h" +#include "Magnum/Vk/Vulkan.h" + +namespace Magnum { namespace Vk { + +/** +@brief Fence creation info +@m_since_latest + +Wraps a @type_vk_keyword{FenceCreateInfo}. See +@ref Vk-Fence-creation "Fence creation" for usage information. +*/ +class MAGNUM_VK_EXPORT FenceCreateInfo { + public: + /** + * @brief Fence creation flag + * + * Wraps @type_vk_keyword{FenceCreateFlagBits}. + * @see @ref Flags, @ref FenceCreateInfo(Flags) + * @m_enum_values_as_keywords + */ + enum class Flag: UnsignedInt { + /** Create the fence in a signaled state */ + Signaled = VK_FENCE_CREATE_SIGNALED_BIT + }; + + /** + * @brief Fence creation flags + * + * Type-safe wrapper for @type_vk_keyword{FenceCreateFlags}. + * @see @ref FenceCreateInfo(Flags) + */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param flags Fence creation flags + * + * The following @type_vk{FenceCreateInfo} fields are pre-filled in + * addition to `sType`, everything else is zero-filled: + * + * - `flags` + */ + /* Fence{device, FenceCreateInfo::Flag::Signaled} doesn't work anyway + (would need an extra conversion from Flag to Flags), so no point in + making this implicit. */ + explicit FenceCreateInfo(Flags flags = {}); + + /** + * @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 FenceCreateInfo(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 FenceCreateInfo(const VkFenceCreateInfo& info); + + /** @brief Underlying @type_vk{FenceCreateInfo} structure */ + VkFenceCreateInfo& operator*() { return _info; } + /** @overload */ + const VkFenceCreateInfo& operator*() const { return _info; } + /** @overload */ + VkFenceCreateInfo* operator->() { return &_info; } + /** @overload */ + const VkFenceCreateInfo* operator->() const { return &_info; } + /** @overload */ + operator const VkFenceCreateInfo*() const { return &_info; } + + private: + VkFenceCreateInfo _info; +}; + +CORRADE_ENUMSET_OPERATORS(FenceCreateInfo::Flags) + +}} + +/* Make the definition complete -- it doesn't make sense to have a CreateInfo + without the corresponding object anyway. */ +#include "Magnum/Vk/Fence.h" + +#endif diff --git a/src/Magnum/Vk/Test/CMakeLists.txt b/src/Magnum/Vk/Test/CMakeLists.txt index fd3dc678a..78e25361e 100644 --- a/src/Magnum/Vk/Test/CMakeLists.txt +++ b/src/Magnum/Vk/Test/CMakeLists.txt @@ -33,6 +33,7 @@ corrade_add_test(VkDeviceFeaturesTest DeviceFeaturesTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkEnumsTest EnumsTest.cpp LIBRARIES MagnumVkTestLib) corrade_add_test(VkExtensionsTest ExtensionsTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkExtensionPropertiesTest ExtensionPropertiesTest.cpp LIBRARIES MagnumVk) +corrade_add_test(VkFenceTest FenceTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkFramebufferTest FramebufferTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkHandleTest HandleTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkImageTest ImageTest.cpp LIBRARIES MagnumVkTestLib) @@ -123,6 +124,7 @@ set_target_properties( VkEnumsTest VkExtensionsTest VkExtensionPropertiesTest + VkFenceTest VkFramebufferTest VkHandleTest VkImageTest @@ -154,6 +156,7 @@ if(BUILD_VK_TESTS) corrade_add_test(VkDeviceVkTest DeviceVkTest.cpp LIBRARIES MagnumVkTestLib MagnumVulkanTester) corrade_add_test(VkDevicePropertiesVkTest DevicePropertiesVkTest.cpp LIBRARIES MagnumVkTestLib MagnumVulkanTester) corrade_add_test(VkExtensionPropertiesVkTest ExtensionPropertiesVkTest.cpp LIBRARIES MagnumVkTestLib) + corrade_add_test(VkFenceVkTest FenceVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester) corrade_add_test(VkFramebufferVkTest FramebufferVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester) corrade_add_test(VkLayerPropertiesVkTest LayerPropertiesVkTest.cpp LIBRARIES MagnumVkTestLib) corrade_add_test(VkImageVkTest ImageVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester) @@ -172,6 +175,7 @@ if(BUILD_VK_TESTS) VkDeviceVkTest VkDevicePropertiesVkTest VkExtensionPropertiesVkTest + VkFenceVkTest VkFramebufferVkTest VkLayerPropertiesVkTest VkImageVkTest diff --git a/src/Magnum/Vk/Test/FenceTest.cpp b/src/Magnum/Vk/Test/FenceTest.cpp new file mode 100644 index 000000000..16a6f1ef8 --- /dev/null +++ b/src/Magnum/Vk/Test/FenceTest.cpp @@ -0,0 +1,95 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 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/FenceCreateInfo.h" + +namespace Magnum { namespace Vk { namespace Test { namespace { + +struct FenceTest: TestSuite::Tester { + explicit FenceTest(); + + void createInfoConstruct(); + void createInfoConstructNoInit(); + void createInfoConstructFromVk(); + + void constructNoCreate(); + void constructCopy(); +}; + +FenceTest::FenceTest() { + addTests({&FenceTest::createInfoConstruct, + &FenceTest::createInfoConstructNoInit, + &FenceTest::createInfoConstructFromVk, + + &FenceTest::constructNoCreate, + &FenceTest::constructCopy}); +} + +void FenceTest::createInfoConstruct() { + FenceCreateInfo info{FenceCreateInfo::Flag::Signaled}; + CORRADE_COMPARE(info->flags, VK_FENCE_CREATE_SIGNALED_BIT); +} + +void FenceTest::createInfoConstructNoInit() { + FenceCreateInfo info{NoInit}; + info->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; + new(&info) FenceCreateInfo{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 FenceTest::createInfoConstructFromVk() { + VkFenceCreateInfo vkInfo; + vkInfo.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; + + FenceCreateInfo info{vkInfo}; + CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); +} + +void FenceTest::constructNoCreate() { + { + Fence view{NoCreate}; + CORRADE_VERIFY(!view.handle()); + } + + /* Implicit construction is not allowed */ + CORRADE_VERIFY(!(std::is_convertible::value)); +} + +void FenceTest::constructCopy() { + CORRADE_VERIFY(!std::is_copy_constructible{}); + CORRADE_VERIFY(!std::is_copy_assignable{}); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Vk::Test::FenceTest) diff --git a/src/Magnum/Vk/Test/FenceVkTest.cpp b/src/Magnum/Vk/Test/FenceVkTest.cpp new file mode 100644 index 000000000..241342d66 --- /dev/null +++ b/src/Magnum/Vk/Test/FenceVkTest.cpp @@ -0,0 +1,98 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 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/FenceCreateInfo.h" +#include "Magnum/Vk/Result.h" +#include "Magnum/Vk/VulkanTester.h" + +namespace Magnum { namespace Vk { namespace Test { namespace { + +struct FenceVkTest: VulkanTester { + explicit FenceVkTest(); + + void construct(); + void constructMove(); + + void wrap(); +}; + +FenceVkTest::FenceVkTest() { + addTests({&FenceVkTest::construct, + &FenceVkTest::constructMove, + + &FenceVkTest::wrap}); +} + +void FenceVkTest::construct() { + { + Fence fence{device(), FenceCreateInfo{FenceCreateInfo::Flag::Signaled}}; + CORRADE_VERIFY(fence.handle()); + CORRADE_COMPARE(fence.handleFlags(), HandleFlag::DestroyOnDestruction); + } + + /* Shouldn't crash or anything */ + CORRADE_VERIFY(true); +} + +void FenceVkTest::constructMove() { + Fence a{device()}; + VkFence handle = a.handle(); + + Fence b = std::move(a); + CORRADE_VERIFY(!a.handle()); + CORRADE_COMPARE(b.handle(), handle); + CORRADE_COMPARE(b.handleFlags(), HandleFlag::DestroyOnDestruction); + + Fence 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 FenceVkTest::wrap() { + VkFence fence{}; + CORRADE_COMPARE(Result(device()->CreateFence(device(), + FenceCreateInfo{}, + nullptr, &fence)), Result::Success); + + auto wrapped = Fence::wrap(device(), fence, HandleFlag::DestroyOnDestruction); + CORRADE_COMPARE(wrapped.handle(), fence); + + /* Release the handle again, destroy by hand */ + CORRADE_COMPARE(wrapped.release(), fence); + CORRADE_VERIFY(!wrapped.handle()); + device()->DestroyFence(device(), fence, nullptr); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Vk::Test::FenceVkTest) diff --git a/src/Magnum/Vk/Vk.h b/src/Magnum/Vk/Vk.h index 9eb00963e..f70ca07c5 100644 --- a/src/Magnum/Vk/Vk.h +++ b/src/Magnum/Vk/Vk.h @@ -49,6 +49,8 @@ class DeviceProperties; enum class DeviceType: Int; class Extension; class ExtensionProperties; +class Fence; +class FenceCreateInfo; class Framebuffer; class FramebufferCreateInfo; enum class HandleFlag: UnsignedByte;