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); } }}}}