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

32
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

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 */
Containers::ArrayView<VkPhysicalDevice> handles{reinterpret_cast<VkPhysicalDevice*>(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());

4
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() {

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

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

Loading…
Cancel
Save