Browse Source

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.
pull/504/head
Vladimír Vondruš 5 years ago
parent
commit
1abb67a119
  1. 5
      doc/snippets/MagnumVk.cpp
  2. 32
      src/Magnum/Vk/Assert.h
  3. 2
      src/Magnum/Vk/DeviceProperties.cpp
  4. 4
      src/Magnum/Vk/Fence.cpp
  5. 8
      src/Magnum/Vk/Test/AssertDisabledTest.cpp
  6. 14
      src/Magnum/Vk/Test/AssertTest.cpp

5
doc/snippets/MagnumVk.cpp

@ -195,8 +195,9 @@ Vk::Device device{instance, std::move(info)};
Vk::Device device{NoCreate}; Vk::Device device{NoCreate};
VkFence fence{}; VkFence fence{};
/* [MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR] */ /* [MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR] */
const Vk::Result result = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(NotReady, const Vk::Result result = MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(
vkGetFenceStatus(device, fence)); vkGetFenceStatus(device, fence),
Vk::Result::NotReady);
if(result == Vk::Result::Success) { if(result == Vk::Result::Success) {
// signaled // signaled
} else { } else {

32
src/Magnum/Vk/Assert.h

@ -82,14 +82,14 @@ You can override this implementation by placing your own
#endif #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 @m_since_latest
A variant of @ref MAGNUM_VK_INTERNAL_ASSERT_SUCCESS() that allows the call to A variant of @ref MAGNUM_VK_INTERNAL_ASSERT_SUCCESS() that allows the call to
return specified @p result in addition to return any of the specified results in addition to
@ref Magnum::Vk::Result::Success "Vk::Result::Success". The value specified in @ref Magnum::Vk::Result::Success "Result::Success". The variadic argument
@p result is directly the (unscoped) enum value and the macro returns the accepts any number of @ref Magnum::Vk::Result "Result" values, the macro then
actual result value. Example usage: returns the actual result value. Example usage:
@snippet MagnumVk.cpp MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR @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)) #if defined(CORRADE_NO_ASSERT) || (defined(CORRADE_STANDARD_ASSERT) && defined(NDEBUG))
/* Defining it to just Magnum::Vk::Result(call) causes ugly warnings with /* Defining it to just Magnum::Vk::Result(call) causes ugly warnings with
asserts disabled, so it has to be a lambda even here :( */ 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); \ return Magnum::Vk::Result(call); \
}() }()
#elif defined(CORRADE_STANDARD_ASSERT) #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); \ 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); \ for(const Magnum::Vk::Result _CORRADE_HELPER_PASTE(magnumVkResultCandidate, __LINE__): {Magnum::Vk::Result::Success, __VA_ARGS__}) { \
return _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__); \ if(_CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) == _CORRADE_HELPER_PASTE(magnumVkResultCandidate, __LINE__)) \
return _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__); \
} \
assert(false); \
}() }()
#else #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); \ 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) { \ for(const Magnum::Vk::Result _CORRADE_HELPER_PASTE(magnumVkResultCandidate, __LINE__): {Magnum::Vk::Result::Success, __VA_ARGS__}) { \
Corrade::Utility::Error{Corrade::Utility::Error::defaultOutput()} << "Call " #call " failed with" << _CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) << "at " __FILE__ ":" CORRADE_LINE_STRING; \ if(_CORRADE_HELPER_PASTE(magnumVkResult, __LINE__) == _CORRADE_HELPER_PASTE(magnumVkResultCandidate, __LINE__)) \
std::abort(); \ 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
#endif #endif

2
src/Magnum/Vk/DeviceProperties.cpp

@ -562,7 +562,7 @@ UnsignedInt enumerateDevicesInto(Instance& instance, Containers::ArrayView<Devic
/* Allocate memory for the output, fetch the handles into it */ /* Allocate memory for the output, fetch the handles into it */
Containers::ArrayView<VkPhysicalDevice> handles{reinterpret_cast<VkPhysicalDevice*>(out.data()), out.size()}; Containers::ArrayView<VkPhysicalDevice> handles{reinterpret_cast<VkPhysicalDevice*>(out.data()), out.size()};
UnsignedInt count = 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 */ /* Expect the final count isn't larger than the output array */
CORRADE_INTERNAL_ASSERT(count <= out.size()); CORRADE_INTERNAL_ASSERT(count <= out.size());

4
src/Magnum/Vk/Fence.cpp

@ -78,7 +78,7 @@ Fence& Fence::operator=(Fence&& other) noexcept {
} }
bool Fence::status() { 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() { void Fence::reset() {
@ -86,7 +86,7 @@ void Fence::reset() {
} }
bool Fence::wait(const std::chrono::nanoseconds timeout) { 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() { void Fence::wait() {

8
src/Magnum/Vk/Test/AssertDisabledTest.cpp

@ -75,7 +75,7 @@ void AssertDisabledTest::successOr() {
Result a = Result::ErrorUnknown; Result a = Result::ErrorUnknown;
Result r = Result::ErrorExtensionNotPresent; 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(a, Result::ErrorExtensionNotPresent);
CORRADE_COMPARE(a2, a); CORRADE_COMPARE(a2, a);
@ -83,7 +83,7 @@ void AssertDisabledTest::successOr() {
/* Test also that a standalone macro won't cause warnings about unused /* Test also that a standalone macro won't cause warnings about unused
expression results */ expression results */
MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(ErrorDeviceLost, Result::ErrorDeviceLost); MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(Result::ErrorDeviceLost, Result::ErrorDeviceLost);
} }
void AssertDisabledTest::vkSuccess() { void AssertDisabledTest::vkSuccess() {
@ -104,7 +104,7 @@ void AssertDisabledTest::vkSuccessOr() {
VkResult b = VK_ERROR_UNKNOWN; VkResult b = VK_ERROR_UNKNOWN;
VkResult s = VK_ERROR_EXTENSION_NOT_PRESENT; 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(Result(b), Result::ErrorExtensionNotPresent);
CORRADE_COMPARE(b2, Result(b)); CORRADE_COMPARE(b2, Result(b));
@ -112,7 +112,7 @@ void AssertDisabledTest::vkSuccessOr() {
/* Test also that a standalone macro won't cause warnings about unused /* Test also that a standalone macro won't cause warnings about unused
expression results */ 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);
} }
}}}} }}}}

14
src/Magnum/Vk/Test/AssertTest.cpp

@ -81,18 +81,19 @@ void AssertTest::success() {
void AssertTest::successOr() { void AssertTest::successOr() {
Result a = Result::ErrorUnknown; 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); CORRADE_COMPARE(a2, a);
Result r = _failAssertSuccessOr ? Result::ErrorExtensionNotPresent : Result::Incomplete; 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(a, Result::Incomplete);
CORRADE_COMPARE(a3, a); CORRADE_COMPARE(a3, a);
/* Test also that a standalone macro won't cause warnings about unused /* Test also that a standalone macro won't cause warnings about unused
expression results */ expression results */
MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(ErrorDeviceLost, Result::ErrorDeviceLost); MAGNUM_VK_INTERNAL_ASSERT_SUCCESS_OR(Result::ErrorDeviceLost, Result::ErrorDeviceLost);
} }
void AssertTest::vkSuccess() { void AssertTest::vkSuccess() {
@ -106,18 +107,19 @@ void AssertTest::vkSuccess() {
void AssertTest::vkSuccessOr() { void AssertTest::vkSuccessOr() {
VkResult a = VK_ERROR_UNKNOWN; 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)); CORRADE_COMPARE(a2, Result(a));
VkResult s = _failAssertVkSuccessOr ? VK_ERROR_EXTENSION_NOT_PRESENT : VK_INCOMPLETE; 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(Result(a), Result::Incomplete);
CORRADE_COMPARE(a3, Result(a)); CORRADE_COMPARE(a3, Result(a));
/* Test also that a standalone macro won't cause warnings about unused /* Test also that a standalone macro won't cause warnings about unused
expression results */ 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);
} }
}}}} }}}}

Loading…
Cancel
Save