From 1abb67a11926450cb01fa29d04455f57641989e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 14 Mar 2021 20:26:46 +0100 Subject: [PATCH] Vk: allow multiple values in MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(). Breaking this macro yet again, sorry -- now the result values are specified last and there can be any number of them, however they need to be all prefixed, as adding the prefix implicitly with the macro would be too much of a pain to implement, especially given the poor preprocessor capabilities of MSVC. --- doc/snippets/MagnumVk.cpp | 5 ++-- src/Magnum/Vk/Assert.h | 32 +++++++++++++---------- src/Magnum/Vk/DeviceProperties.cpp | 2 +- src/Magnum/Vk/Fence.cpp | 4 +-- src/Magnum/Vk/Test/AssertDisabledTest.cpp | 8 +++--- src/Magnum/Vk/Test/AssertTest.cpp | 14 +++++----- 6 files changed, 36 insertions(+), 29 deletions(-) diff --git a/doc/snippets/MagnumVk.cpp b/doc/snippets/MagnumVk.cpp index a3c8c966e..72a47e49c 100644 --- a/doc/snippets/MagnumVk.cpp +++ b/doc/snippets/MagnumVk.cpp @@ -195,8 +195,9 @@ Vk::Device device{instance, std::move(info)}; Vk::Device device{NoCreate}; VkFence fence{}; /* [MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR] */ -const Vk::Result result = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(NotReady, - vkGetFenceStatus(device, fence)); +const Vk::Result result = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR( + vkGetFenceStatus(device, fence), + Vk::Result::NotReady); if(result == Vk::Result::Success) { // signaled } else { diff --git a/src/Magnum/Vk/Assert.h b/src/Magnum/Vk/Assert.h index 60b860095..ca8305779 100644 --- a/src/Magnum/Vk/Assert.h +++ b/src/Magnum/Vk/Assert.h @@ -82,14 +82,14 @@ You can override this implementation by placing your own #endif /** -@brief Assert that a Vulkan function call succeeds or returns the specified result +@brief Assert that a Vulkan function call succeeds or returns any of the specified results @m_since_latest A variant of @ref MAGNUM_VK_INTERNAL_ASSERT_SUCCESS() that allows the call to -return specified @p result in addition to -@ref Magnum::Vk::Result::Success "Vk::Result::Success". The value specified in -@p result is directly the (unscoped) enum value and the macro returns the -actual result value. Example usage: +return any of the specified results in addition to +@ref Magnum::Vk::Result::Success "Result::Success". The variadic argument +accepts any number of @ref Magnum::Vk::Result "Result" values, the macro then +returns the actual result value. Example usage: @snippet MagnumVk.cpp MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR @@ -103,26 +103,30 @@ including the @ref Magnum/Vk/Assert.h header. #if defined(CORRADE_NO_ASSERT) || (defined(CORRADE_STANDARD_ASSERT) && defined(NDEBUG)) /* Defining it to just Magnum::Vk::Result(call) causes ugly warnings with asserts disabled, so it has to be a lambda even here :( */ -#define MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(result, call) \ +#define MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(call, ...) \ [&]() { \ return Magnum::Vk::Result(call); \ }() #elif defined(CORRADE_STANDARD_ASSERT) -#define MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(result, call) \ +#define MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(call, ...) \ [&]() { \ const Magnum::Vk::Result _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) = Magnum::Vk::Result(call); \ - assert(_CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) == Magnum::Vk::Result::Success || _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) == Magnum::Vk::Result::result); \ - return _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__); \ + for(const Magnum::Vk::Result _CORRADE_HELPER_PASTE(magnumVkResultCandidate, __LINE__): {Magnum::Vk::Result::Success, __VA_ARGS__}) { \ + if(_CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) == _CORRADE_HELPER_PASTE(magnumVkResultCandidate, __LINE__)) \ + return _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__); \ + } \ + assert(false); \ }() #else -#define MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(result, call) \ +#define MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(call, ...) \ [&]() { \ const Magnum::Vk::Result _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) = Magnum::Vk::Result(call); \ - if(_CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) != Magnum::Vk::Result::Success && _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) != Magnum::Vk::Result::result) { \ - Corrade::Utility::Error{Corrade::Utility::Error::defaultOutput()} << "Call " #call " failed with" << _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) << "at " __FILE__ ":" CORRADE_LINE_STRING; \ - std::abort(); \ + for(const Magnum::Vk::Result _CORRADE_HELPER_PASTE(magnumVkResultCandidate, __LINE__): {Magnum::Vk::Result::Success, __VA_ARGS__}) { \ + if(_CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) == _CORRADE_HELPER_PASTE(magnumVkResultCandidate, __LINE__)) \ + return _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__); \ } \ - return _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__); \ + Corrade::Utility::Error{Corrade::Utility::Error::defaultOutput()} << "Call " #call " failed with" << _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) << "at " __FILE__ ":" CORRADE_LINE_STRING; \ + std::abort(); \ }() #endif #endif diff --git a/src/Magnum/Vk/DeviceProperties.cpp b/src/Magnum/Vk/DeviceProperties.cpp index 739c5a8f7..f3c2d3786 100644 --- a/src/Magnum/Vk/DeviceProperties.cpp +++ b/src/Magnum/Vk/DeviceProperties.cpp @@ -562,7 +562,7 @@ UnsignedInt enumerateDevicesInto(Instance& instance, Containers::ArrayView handles{reinterpret_cast(out.data()), out.size()}; UnsignedInt count = out.size(); - MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(Incomplete, instance->EnumeratePhysicalDevices(instance, &count, handles.data())); + MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(instance->EnumeratePhysicalDevices(instance, &count, handles.data()), Result::Incomplete); /* Expect the final count isn't larger than the output array */ CORRADE_INTERNAL_ASSERT(count <= out.size()); diff --git a/src/Magnum/Vk/Fence.cpp b/src/Magnum/Vk/Fence.cpp index 01d4defb6..6c6818699 100644 --- a/src/Magnum/Vk/Fence.cpp +++ b/src/Magnum/Vk/Fence.cpp @@ -78,7 +78,7 @@ Fence& Fence::operator=(Fence&& other) noexcept { } bool Fence::status() { - return MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(NotReady, (**_device).GetFenceStatus(*_device, _handle)) == Result::Success; + return MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR((**_device).GetFenceStatus(*_device, _handle), Result::NotReady) == Result::Success; } void Fence::reset() { @@ -86,7 +86,7 @@ void Fence::reset() { } bool Fence::wait(const std::chrono::nanoseconds timeout) { - return MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(Timeout, (**_device).WaitForFences(*_device, 1, &_handle, true, timeout.count())) == Result::Success; + return MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR((**_device).WaitForFences(*_device, 1, &_handle, true, timeout.count()), Result::Timeout) == Result::Success; } void Fence::wait() { diff --git a/src/Magnum/Vk/Test/AssertDisabledTest.cpp b/src/Magnum/Vk/Test/AssertDisabledTest.cpp index 82f73906b..0221fd51e 100644 --- a/src/Magnum/Vk/Test/AssertDisabledTest.cpp +++ b/src/Magnum/Vk/Test/AssertDisabledTest.cpp @@ -75,7 +75,7 @@ void AssertDisabledTest::successOr() { Result a = Result::ErrorUnknown; Result r = Result::ErrorExtensionNotPresent; - Result a2 = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(Incomplete, a = r); + Result a2 = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(a = r, Result::Incomplete); CORRADE_COMPARE(a, Result::ErrorExtensionNotPresent); CORRADE_COMPARE(a2, a); @@ -83,7 +83,7 @@ void AssertDisabledTest::successOr() { /* Test also that a standalone macro won't cause warnings about unused expression results */ - MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(ErrorDeviceLost, Result::ErrorDeviceLost); + MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(Result::ErrorDeviceLost, Result::ErrorDeviceLost); } void AssertDisabledTest::vkSuccess() { @@ -104,7 +104,7 @@ void AssertDisabledTest::vkSuccessOr() { VkResult b = VK_ERROR_UNKNOWN; VkResult s = VK_ERROR_EXTENSION_NOT_PRESENT; - Result b2 = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(Incomplete, b = s); + Result b2 = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(b = s, Result::Incomplete); CORRADE_COMPARE(Result(b), Result::ErrorExtensionNotPresent); CORRADE_COMPARE(b2, Result(b)); @@ -112,7 +112,7 @@ void AssertDisabledTest::vkSuccessOr() { /* Test also that a standalone macro won't cause warnings about unused expression results */ - MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(ErrorDeviceLost, VK_ERROR_DEVICE_LOST); + MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(VK_ERROR_DEVICE_LOST, Result::ErrorDeviceLost); } }}}} diff --git a/src/Magnum/Vk/Test/AssertTest.cpp b/src/Magnum/Vk/Test/AssertTest.cpp index 1cf5c05a9..c4dae782f 100644 --- a/src/Magnum/Vk/Test/AssertTest.cpp +++ b/src/Magnum/Vk/Test/AssertTest.cpp @@ -81,18 +81,19 @@ void AssertTest::success() { void AssertTest::successOr() { Result a = Result::ErrorUnknown; - Result a2 = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(Incomplete, a = Result::Success); + Result a2 = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(a = Result::Success, Result::Incomplete); CORRADE_COMPARE(a2, a); Result r = _failAssertSuccessOr ? Result::ErrorExtensionNotPresent : Result::Incomplete; - Result a3 = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(Incomplete, a = r); + /* Verify that multiple results work too and all get checked */ + Result a3 = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(a = r, Result::ErrorOutOfDeviceMemory, Result::Incomplete); CORRADE_COMPARE(a, Result::Incomplete); CORRADE_COMPARE(a3, a); /* Test also that a standalone macro won't cause warnings about unused expression results */ - MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(ErrorDeviceLost, Result::ErrorDeviceLost); + MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(Result::ErrorDeviceLost, Result::ErrorDeviceLost); } void AssertTest::vkSuccess() { @@ -106,18 +107,19 @@ void AssertTest::vkSuccess() { void AssertTest::vkSuccessOr() { VkResult a = VK_ERROR_UNKNOWN; - Result a2 = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(Incomplete, a = VK_SUCCESS); + Result a2 = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(a = VK_SUCCESS, Result::Incomplete); CORRADE_COMPARE(a2, Result(a)); VkResult s = _failAssertVkSuccessOr ? VK_ERROR_EXTENSION_NOT_PRESENT : VK_INCOMPLETE; - Result a3 = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(Incomplete, a = s); + /* Verify that multiple results work too and all get checked */ + Result a3 = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(a = s, Result::ErrorOutOfDeviceMemory, Result::Incomplete); CORRADE_COMPARE(Result(a), Result::Incomplete); CORRADE_COMPARE(a3, Result(a)); /* Test also that a standalone macro won't cause warnings about unused expression results */ - MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(ErrorDeviceLost, VK_ERROR_DEVICE_LOST); + MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(VK_ERROR_DEVICE_LOST, Result::ErrorDeviceLost); } }}}}