From 65552a6c26cf5a50b915088579551275baae91e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 12 May 2020 23:32:11 +0200 Subject: [PATCH] Vk: add Version enum, utities for version comparison and extraction. Same as the VK_VERSION_*() macros but without C-style casts that produce warnings. --- src/Magnum/Vk/CMakeLists.txt | 4 +- src/Magnum/Vk/Test/CMakeLists.txt | 1 + src/Magnum/Vk/Test/VersionTest.cpp | 121 +++++++++++++++++++++++++ src/Magnum/Vk/Version.cpp | 41 +++++++++ src/Magnum/Vk/Version.h | 136 +++++++++++++++++++++++++++++ src/Magnum/Vk/Vk.h | 1 + 6 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 src/Magnum/Vk/Test/VersionTest.cpp create mode 100644 src/Magnum/Vk/Version.cpp create mode 100644 src/Magnum/Vk/Version.h diff --git a/src/Magnum/Vk/CMakeLists.txt b/src/Magnum/Vk/CMakeLists.txt index 83a99e511..0a8962722 100644 --- a/src/Magnum/Vk/CMakeLists.txt +++ b/src/Magnum/Vk/CMakeLists.txt @@ -27,7 +27,8 @@ find_package(Vulkan REQUIRED) set(MagnumVk_SRCS - Result.cpp) + Result.cpp + Version.cpp) set(MagnumVk_GracefulAssert_SRCS Enums.cpp) @@ -36,6 +37,7 @@ set(MagnumVk_HEADERS Enums.h Integration.h Result.h + Version.h Vk.h Vulkan.h diff --git a/src/Magnum/Vk/Test/CMakeLists.txt b/src/Magnum/Vk/Test/CMakeLists.txt index 9948569df..42ef5c923 100644 --- a/src/Magnum/Vk/Test/CMakeLists.txt +++ b/src/Magnum/Vk/Test/CMakeLists.txt @@ -27,3 +27,4 @@ corrade_add_test(VkEnumsTest EnumsTest.cpp LIBRARIES MagnumVkTestLib) corrade_add_test(VkIntegrationTest IntegrationTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkResultTest ResultTest.cpp LIBRARIES MagnumVk) +corrade_add_test(VkVersionTest VersionTest.cpp LIBRARIES MagnumVk) diff --git a/src/Magnum/Vk/Test/VersionTest.cpp b/src/Magnum/Vk/Test/VersionTest.cpp new file mode 100644 index 000000000..91af9026f --- /dev/null +++ b/src/Magnum/Vk/Test/VersionTest.cpp @@ -0,0 +1,121 @@ +/* + 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 + +#include "Magnum/Magnum.h" +#include "Magnum/Vk/Version.h" +#include "Magnum/Vk/Vulkan.h" + +namespace Magnum { namespace Vk { namespace Test { namespace { + +struct VersionTest: TestSuite::Tester { + explicit VersionTest(); + + void packing(); + void comparison(); + + void debug(); +}; + +VersionTest::VersionTest() { + addTests({&VersionTest::packing, + &VersionTest::comparison, + + &VersionTest::debug}); +} + +void VersionTest::packing() { + #ifdef CORRADE_TARGET_GCC + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wold-style-cast" + #endif + constexpr Version packed = version(1, 5, 789); + constexpr UnsignedInt major = versionMajor(packed); + constexpr UnsignedInt minor = versionMinor(packed); + constexpr UnsignedInt patch = versionPatch(packed); + CORRADE_COMPARE(packed, Version(VK_MAKE_VERSION(1, 5, 789))); + CORRADE_COMPARE(major, VK_VERSION_MAJOR(packed)); + CORRADE_COMPARE(minor, VK_VERSION_MINOR(packed)); + CORRADE_COMPARE(patch, VK_VERSION_PATCH(packed)); + CORRADE_COMPARE(major, 1); + CORRADE_COMPARE(minor, 5); + CORRADE_COMPARE(patch, 789); + #ifdef CORRADE_TARGET_GCC + #pragma GCC diagnostic pop + #endif +} + +void VersionTest::comparison() { + CORRADE_VERIFY(!(version(1, 5, 3) < version(1, 5, 3))); + CORRADE_VERIFY(!(version(1, 5, 3) > version(1, 5, 3))); + + CORRADE_VERIFY(version(1, 5, 3) < version(1, 5, 4)); + CORRADE_VERIFY(version(1, 5, 4) > version(1, 5, 3)); + CORRADE_VERIFY(!(version(1, 5, 3) > version(1, 5, 4))); + CORRADE_VERIFY(!(version(1, 5, 4) < version(1, 5, 3))); + + CORRADE_VERIFY(version(1, 5, 3) < version(1, 6, 3)); + CORRADE_VERIFY(version(1, 6, 3) > version(1, 5, 3)); + CORRADE_VERIFY(!(version(1, 5, 3) > version(1, 6, 3))); + CORRADE_VERIFY(!(version(1, 6, 3) < version(1, 5, 3))); + + CORRADE_VERIFY(version(1, 5, 3) < version(2, 5, 3)); + CORRADE_VERIFY(version(2, 5, 3) > version(1, 5, 3)); + CORRADE_VERIFY(!(version(1, 5, 3) > version(2, 5, 3))); + CORRADE_VERIFY(!(version(2, 5, 3) < version(1, 5, 3))); + + CORRADE_VERIFY(version(1, 5, 3) <= version(1, 5, 3)); + CORRADE_VERIFY(version(1, 5, 3) >= version(1, 5, 3)); + + CORRADE_VERIFY(version(1, 5, 3) <= version(1, 5, 4)); + CORRADE_VERIFY(version(1, 5, 4) >= version(1, 5, 3)); + CORRADE_VERIFY(!(version(1, 5, 3) >= version(1, 5, 4))); + CORRADE_VERIFY(!(version(1, 5, 4) <= version(1, 5, 3))); + + CORRADE_VERIFY(version(1, 5, 3) <= version(1, 6, 3)); + CORRADE_VERIFY(version(1, 6, 3) >= version(1, 5, 3)); + CORRADE_VERIFY(!(version(1, 5, 3) >= version(1, 6, 3))); + CORRADE_VERIFY(!(version(1, 6, 3) <= version(1, 5, 3))); + + CORRADE_VERIFY(version(1, 5, 3) <= version(2, 5, 3)); + CORRADE_VERIFY(version(2, 5, 3) >= version(1, 5, 3)); + CORRADE_VERIFY(!(version(1, 5, 3) >= version(2, 5, 3))); + CORRADE_VERIFY(!(version(2, 5, 3) <= version(1, 5, 3))); +} + +void VersionTest::debug() { + std::ostringstream out; + Debug{&out} << Version::Vk12 << version(1, 5, 789) << Version::None + /* packed should omit "Vulkan" */ + << Debug::packed << version(20, 6); + CORRADE_COMPARE(out.str(), "Vulkan 1.2 Vulkan 1.5.789 Vulkan 1023.1023.4095 20.6\n"); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Vk::Test::VersionTest) diff --git a/src/Magnum/Vk/Version.cpp b/src/Magnum/Vk/Version.cpp new file mode 100644 index 000000000..d4f8b7cb5 --- /dev/null +++ b/src/Magnum/Vk/Version.cpp @@ -0,0 +1,41 @@ +/* + 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 "Version.h" + +#include + +namespace Magnum { namespace Vk { + +Debug& operator<<(Debug& debug, const Version value) { + if(!(debug.immediateFlags() & Debug::Flag::Packed)) + debug << "Vulkan"; + debug << versionMajor(value) << Debug::nospace << "." << Debug::nospace << versionMinor(value); + if(const UnsignedInt patch = versionPatch(value)) + debug << Debug::nospace << "." << Debug::nospace << patch; + return debug; +} + +}} diff --git a/src/Magnum/Vk/Version.h b/src/Magnum/Vk/Version.h new file mode 100644 index 000000000..5e27bef36 --- /dev/null +++ b/src/Magnum/Vk/Version.h @@ -0,0 +1,136 @@ +#ifndef Magnum_Vk_Version_h +#define Magnum_Vk_Version_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 Enum @ref Magnum::Vk::Version, function @ref Magnum::Vk::version(), @ref Magnum::Vk::versionMajor(), @ref Magnum::Vk::versionMinor(), @ref Magnum::Vk::versionPatch() + * @m_since_latest + */ + +#include "Magnum/Magnum.h" +#include "Magnum/Vk/visibility.h" + +namespace Magnum { namespace Vk { + +/** +@brief Vulkan version +@m_since_latest + +@see @ref version(), @ref versionMajor(), @ref versionMinor(), @ref versionPatch() +*/ +enum class Version: UnsignedInt { + None = 0xffffffffu, /**< Unspecified */ + + /* Not using VK_MAKE_VERSION() because it would warn about C-style casts */ + Vk10 = (1 << 22) | (0 << 12), /**< Vulkan 1.0 */ + Vk11 = (1 << 22) | (1 << 12), /**< Vulkan 1.1 */ + Vk12 = (1 << 22) | (2 << 12) /**< Vulkan 1.2 */ +}; + +/** +@brief Create a version from components +@m_since_latest + +Equivalent to @def_vk_keyword{MAKE_VERSION}, but without C-style casts. +*/ +constexpr Version version(UnsignedInt major, UnsignedInt minor, UnsignedInt patch = 0) { + return Version((major << 22) | (minor << 12) | patch); +} + +/** +@brief Extract major version number from a packed representation +@m_since_latest + +Equivalent to @def_vk_keyword{VERSION_MAJOR}, but without C-style casts. +*/ +constexpr UnsignedInt versionMajor(Version version) { + return UnsignedInt(version) >> 22; +} + +/** +@brief Extract minor version number from a packed representation +@m_since_latest + +Equivalent to @def_vk_keyword{VERSION_MINOR}, but without C-style casts. +*/ +constexpr UnsignedInt versionMinor(Version version) { + return (UnsignedInt(version) >> 12) & 0x3ff; +} + +/** +@brief Extract minor version number from a packed representation +@m_since_latest + +Equivalent to @def_vk_keyword{VERSION_PATCH}, but without C-style casts. +*/ +constexpr UnsignedInt versionPatch(Version version) { + return UnsignedInt(version) & 0xfff; +} + +/** +@brief Whether a version is smaller than the other +@m_since_latest +*/ +constexpr bool operator<(Version a, Version b) { + return UnsignedInt(a) < UnsignedInt(b); +} + +/** +@brief Whether a version is smaller than or equal to the other +@m_since_latest +*/ +constexpr bool operator<=(Version a, Version b) { + return UnsignedInt(a) <= UnsignedInt(b); +} + +/** +@brief Whether a version is greater than or equal to the other +@m_since_latest +*/ +constexpr bool operator>=(Version a, Version b) { + return UnsignedInt(a) >= UnsignedInt(b); +} + +/** +@brief Whether a version is greater than the other +@m_since_latest +*/ +constexpr bool operator>(Version a, Version b) { + return UnsignedInt(a) > UnsignedInt(b); +} + +/** +@debugoperatorenum{Version} +@m_since_latest + +Prints the version as @cb{.shell-session} .. @ce, or just +as @cb{.shell-session} . @ce if patch is zero. +*/ +MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, Version value); + +}} + +#endif diff --git a/src/Magnum/Vk/Vk.h b/src/Magnum/Vk/Vk.h index cae3d1d96..b9725d3ea 100644 --- a/src/Magnum/Vk/Vk.h +++ b/src/Magnum/Vk/Vk.h @@ -35,6 +35,7 @@ namespace Magnum { namespace Vk { #ifndef DOXYGEN_GENERATING_OUTPUT enum class Result: Int; +enum class Version: UnsignedInt; #endif }}