diff --git a/doc/changelog.dox b/doc/changelog.dox index 71acc87db..966356a7b 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -95,6 +95,11 @@ See also: @ref Platform::Sdl2Application::InputEvent::event() "event()" accessors to make it possible to access raw `SDL_Event` data +@subsubsection changelog-latest-new-vk Vk library + +- Conversion between Magnum math types and math-related Vulkan types in a + new @ref Magnum/Vk/Integration.h header + @subsection changelog-latest-changes Changes and improvements @subsubsection changelog-latest-changes-audio Audio library diff --git a/doc/snippets/CMakeLists.txt b/doc/snippets/CMakeLists.txt index c47560526..c19d2ffbf 100644 --- a/doc/snippets/CMakeLists.txt +++ b/doc/snippets/CMakeLists.txt @@ -149,6 +149,13 @@ if(WITH_SCENEGRAPH) endif() endif() +if(WITH_VK) + add_library(snippets-MagnumVk STATIC MagnumVk.cpp) + target_link_libraries(snippets-MagnumVk PRIVATE MagnumVk) + set_target_properties(snippets-MagnumVk + PROPERTIES FOLDER "Magnum/doc/snippets") +endif() + if(WITH_SDL2APPLICATION) add_executable(getting-started getting-started.cpp) add_executable(getting-started-blue getting-started-blue.cpp) diff --git a/doc/snippets/MagnumVk.cpp b/doc/snippets/MagnumVk.cpp new file mode 100644 index 000000000..6043a4483 --- /dev/null +++ b/doc/snippets/MagnumVk.cpp @@ -0,0 +1,44 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + 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 "Magnum/Magnum.h" +#include "Magnum/Math/Color.h" +#include "Magnum/Vk/Integration.h" + +using namespace Magnum; + +int main() { +{ +/* [Integration] */ +VkOffset2D a{64, 32}; +Vector2i b(a); + +using namespace Math::Literals; +VkClearColorValue c = VkClearColorValue(0xff9391_srgbf); +/* [Integration] */ +static_cast(b); +static_cast(c); +} +} diff --git a/src/Magnum/Vk/CMakeLists.txt b/src/Magnum/Vk/CMakeLists.txt index 743ccc93e..aec2fe8e8 100644 --- a/src/Magnum/Vk/CMakeLists.txt +++ b/src/Magnum/Vk/CMakeLists.txt @@ -36,6 +36,7 @@ set(MagnumVk_GracefulAssert_SRCS Enums.cpp) set(MagnumVk_HEADERS Enums.h + Integration.h Vk.h Vulkan.h diff --git a/src/Magnum/Vk/Integration.h b/src/Magnum/Vk/Integration.h new file mode 100644 index 000000000..33aacfc4e --- /dev/null +++ b/src/Magnum/Vk/Integration.h @@ -0,0 +1,247 @@ +#ifndef Magnum_Vk_Integration_h +#define Magnum_Vk_Integration_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + 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 Conversion of Vulkan math types + +Provides conversion for the following types: + +| Magnum type | Equivalent Vulkan type | +| ------------------------------------- | ----------------------------- | +| @ref Magnum::Vector2i "Vector2i" | @type_vk{Offset2D}, @type_vk{Extent2D} | +| @ref Magnum::Vector3i "Vector3i" | @type_vk{Offset3D}, @type_vk{Extent3D} | +| @ref Magnum::Vector2ui "Vector2ui" | @type_vk{Extent2D} | +| @ref Magnum::Vector3ui "Vector3ui" | @type_vk{Extent3D} | +| @ref Magnum::Vector4 "Vector4", @ref Magnum::Color4 "Color4", @ref Magnum::Vector4i "Vector4i", @ref Magnum::Vector4ui "Vector4ui" | @type_vk{ClearColorValue} | +| @ref Magnum::Vector3 "Vector3", @ref Magnum::Color3 "Color3" | @type_vk{ClearColorValue} | +| @ref Magnum::Range3D "Range3D" | @type_vk{Viewport} | +| @ref Magnum::Range2Di "Range2Di" | @type_vk{Rect2D} | +| @ref Magnum::Range3Di "Range3Di" | @type_vk{ClearRect} | + +@type_vk{ClearColorValue} is an @cpp union @ce, so it's convertible from/to a +floating-point type as well as integer types, but you have to ensure the type +is correct for the API call it'll used in. Conversion of @type_vk{ClearColorValue} +to @ref Magnum::Color3 "Color3" is not allowed, as it would lead to loss of the +alpha value. In the other direction, alpha is set to @cpp 1.0f @ce. + +Third dimension of @type_vk{Viewport} is a depth range, third dimension of +@type_vk{ClearRect} is an attachment layer range. In both cases you can use +@ref Magnum::Math::Range3D::xy() "Range3D::xy()" to slice it into a +two-dimensional range type. + +Since Magnum uses a signed type for all offsets, sizes and rectangles, the +unsigned @type_vk{Extent2D} / @type_vk{Extent3D} types are convertible to +signed types as well. The @type_vk{Rect2D} and @type_vk{ClearRect} is a mixed +unsigned + signed type, which corresponds to a signed range on Magnum side. + +Example usage: + +@snippet MagnumVk.cpp Integration + +@see @ref types-thirdparty-integration +*/ + +#include "Magnum/Vk/Vulkan.h" +#include "Magnum/Math/Range.h" + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Magnum { namespace Math { namespace Implementation { + +template<> struct VectorConverter<2, Int, VkOffset2D> { + constexpr static Vector<2, Int> from(const VkOffset2D& other) { + return {other.x, other.y}; + } + + constexpr static VkOffset2D to(const Vector<2, Int>& other) { + return {other[0], other[1]}; + } +}; + +template<> struct VectorConverter<3, Int, VkOffset3D> { + constexpr static Vector<3, Int> from(const VkOffset3D& other) { + return {other.x, other.y, other.z}; + } + + constexpr static VkOffset3D to(const Vector<3, Int>& other) { + return {other[0], other[1], other[2]}; + } +}; + +template<> struct VectorConverter<2, UnsignedInt, VkExtent2D> { + constexpr static Vector<2, UnsignedInt> from(const VkExtent2D& other) { + return {other.width, other.height}; + } + + constexpr static VkExtent2D to(const Vector<2, UnsignedInt>& other) { + return {other[0], other[1]}; + } +}; + +template<> struct VectorConverter<2, Int, VkExtent2D> { + constexpr static Vector<2, Int> from(const VkExtent2D& other) { + return {Int(other.width), Int(other.height)}; + } + + constexpr static VkExtent2D to(const Vector<2, Int>& other) { + return {UnsignedInt(other[0]), UnsignedInt(other[1])}; + } +}; + +template<> struct VectorConverter<3, UnsignedInt, VkExtent3D> { + constexpr static Vector<3, UnsignedInt> from(const VkExtent3D& other) { + return {other.width, other.height, other.depth}; + } + + constexpr static VkExtent3D to(const Vector<3, UnsignedInt>& other) { + return {other[0], other[1], other[2]}; + } +}; + +template<> struct VectorConverter<3, Int, VkExtent3D> { + constexpr static Vector<3, Int> from(const VkExtent3D& other) { + return {Int(other.width), Int(other.height), Int(other.depth)}; + } + + constexpr static VkExtent3D to(const Vector<3, Int>& other) { + return {UnsignedInt(other[0]), UnsignedInt(other[1]), UnsignedInt(other[2])}; + } +}; + +template<> struct VectorConverter<4, Float, VkClearColorValue> { + constexpr static Vector<4, Float> from(const VkClearColorValue& other) { + return {other.float32[0], other.float32[1], other.float32[2], other.float32[3]}; + } + + /* Can this even be constexpr? */ + static VkClearColorValue to(const Vector<4, Float>& other) { + VkClearColorValue out; + out.float32[0] = other[0]; + out.float32[1] = other[1]; + out.float32[2] = other[2]; + out.float32[3] = other[3]; + return out; + } +}; + +template<> struct VectorConverter<4, Int, VkClearColorValue> { + constexpr static Vector<4, Int> from(const VkClearColorValue& other) { + return {other.int32[0], other.int32[1], other.int32[2], other.int32[3]}; + } + + /* Can this even be constexpr? */ + static VkClearColorValue to(const Vector<4, Int>& other) { + VkClearColorValue out; + out.int32[0] = other[0]; + out.int32[1] = other[1]; + out.int32[2] = other[2]; + out.int32[3] = other[3]; + return out; + } +}; + +template<> struct VectorConverter<4, UnsignedInt, VkClearColorValue> { + constexpr static Vector<4, UnsignedInt> from(const VkClearColorValue& other) { + return {other.uint32[0], other.uint32[1], other.uint32[2], other.uint32[3]}; + } + + /* Can this even be constexpr? */ + static VkClearColorValue to(const Vector<4, UnsignedInt>& other) { + VkClearColorValue out; + out.uint32[0] = other[0]; + out.uint32[1] = other[1]; + out.uint32[2] = other[2]; + out.uint32[3] = other[3]; + return out; + } +}; + +template<> struct VectorConverter<3, Float, VkClearColorValue> { + /* VkClearColorValue -> Vector3 not provided, as it loses information */ + + /* Can this even be constexpr? */ + static VkClearColorValue to(const Vector<3, Float>& other) { + VkClearColorValue out; + out.float32[0] = other[0]; + out.float32[1] = other[1]; + out.float32[2] = other[2]; + out.float32[3] = 1.0f; + return out; + } +}; + +template<> struct RangeConverter<3, Float, VkViewport> { + constexpr static Range<3, Float> from(const VkViewport& other) { + return {{other.x, other.y, other.minDepth}, + {other.x + other.width, other.y + other.height, other.maxDepth}}; + } + + constexpr static VkViewport to(const Range<3, Float>& other) { + return {other.min().x(), other.min().y(), + other.max().x() - other.min().x(), + other.max().y() - other.min().y(), + other.min().z(), other.max().z()}; + } +}; + +template<> struct RangeConverter<2, Int, VkRect2D> { + constexpr static Range<2, Int> from(const VkRect2D& other) { + /* Can't use fromSize() as it's not constexpr */ + return {Vector<2, Int>(other.offset), + {other.offset.x + Int(other.extent.width), + other.offset.y + Int(other.extent.height)}}; + } + + constexpr static VkRect2D to(const Range<2, Int>& other) { + /* Can't use VkExtent2D(other.size()) as it's not constexpr */ + return {VkOffset2D(other.min()), + {UnsignedInt(other.max().x() - other.min().x()), + UnsignedInt(other.max().y() - other.min().y())}}; + } +}; + +template<> struct RangeConverter<3, Int, VkClearRect> { + constexpr static Range<3, Int> from(const VkClearRect& other) { + /* Can't use fromSize() as it's not constexpr */ + return {{Vector<2, Int>(other.rect.offset), Int(other.baseArrayLayer)}, + {other.rect.offset.x + Int(other.rect.extent.width), + other.rect.offset.y + Int(other.rect.extent.height), + Int(other.baseArrayLayer + other.layerCount)}}; + } + + constexpr static VkClearRect to(const Range<3, Int>& other) { + return {{VkOffset2D(other.min().xy()), + {UnsignedInt(other.max().x() - other.min().x()), + UnsignedInt(other.max().y() - other.min().y())}}, + UnsignedInt(other.min().z()), + UnsignedInt(other.max().z() - other.min().z())}; + } +}; + +}}} +#endif + +#endif diff --git a/src/Magnum/Vk/Test/CMakeLists.txt b/src/Magnum/Vk/Test/CMakeLists.txt index db3c5a403..97245764c 100644 --- a/src/Magnum/Vk/Test/CMakeLists.txt +++ b/src/Magnum/Vk/Test/CMakeLists.txt @@ -25,3 +25,4 @@ # corrade_add_test(VkEnumsTest EnumsTest.cpp LIBRARIES MagnumVkTestLib) +corrade_add_test(VkIntegrationTest IntegrationTest.cpp LIBRARIES MagnumVk) diff --git a/src/Magnum/Vk/Test/IntegrationTest.cpp b/src/Magnum/Vk/Test/IntegrationTest.cpp new file mode 100644 index 000000000..0e17d51af --- /dev/null +++ b/src/Magnum/Vk/Test/IntegrationTest.cpp @@ -0,0 +1,294 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + 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 "Magnum/Magnum.h" +#include "Magnum/Math/Color.h" +#include "Magnum/Vk/Integration.h" + +namespace Magnum { namespace Vk { namespace Test { + +struct IntegrationTest: TestSuite::Tester { + explicit IntegrationTest(); + + void vkOffset2D(); + void vkOffset3D(); + void vkExtent2D(); + void vkExtent3D(); + void vkExtent2DSigned(); + void vkExtent3DSigned(); + void vkClearColorValueFloat(); + void vkClearColorValueSigned(); + void vkClearColorValueUnsigned(); + void vkClearColorValue3(); + void vkViewport(); + void vkRect2D(); + void vkClearRect(); +}; + +IntegrationTest::IntegrationTest() { + addTests({&IntegrationTest::vkOffset2D, + &IntegrationTest::vkOffset3D, + &IntegrationTest::vkExtent2D, + &IntegrationTest::vkExtent3D, + &IntegrationTest::vkExtent2DSigned, + &IntegrationTest::vkExtent3DSigned, + &IntegrationTest::vkClearColorValueFloat, + &IntegrationTest::vkClearColorValueSigned, + &IntegrationTest::vkClearColorValueUnsigned, + &IntegrationTest::vkClearColorValue3, + &IntegrationTest::vkViewport, + &IntegrationTest::vkRect2D, + &IntegrationTest::vkClearRect}); +} + +void IntegrationTest::vkOffset2D() { + Vector2i a{1, -2}; + VkOffset2D b(a); + Vector2i c(b); + CORRADE_COMPARE(b.x, 1); + CORRADE_COMPARE(b.y, -2); + CORRADE_COMPARE(c, (Vector2i{1, -2})); + + constexpr Vector2i ca{1, -2}; + constexpr VkOffset2D cb(ca); + constexpr Vector2i cc(cb); + CORRADE_COMPARE(cb.x, 1); + CORRADE_COMPARE(cb.y, -2); + CORRADE_COMPARE(cc, (Vector2i{1, -2})); +} + +void IntegrationTest::vkOffset3D() { + Vector3i a{-3, 2, 1}; + VkOffset3D b(a); + Vector3i c(b); + CORRADE_COMPARE(b.x, -3); + CORRADE_COMPARE(b.y, 2); + CORRADE_COMPARE(b.z, 1); + CORRADE_COMPARE(c, (Vector3i{-3, 2, 1})); + + constexpr Vector3i ca{-3, 2, 1}; + constexpr VkOffset3D cb(ca); + constexpr Vector3i cc(cb); + CORRADE_COMPARE(cb.x, -3); + CORRADE_COMPARE(cb.y, 2); + CORRADE_COMPARE(cb.z, 1); + CORRADE_COMPARE(cc, (Vector3i{-3, 2, 1})); +} + +void IntegrationTest::vkExtent2D() { + Vector2ui a{3526872522, 2}; + VkExtent2D b(a); + Vector2ui c(b); + CORRADE_COMPARE(b.width, 3526872522); + CORRADE_COMPARE(b.height, 2); + CORRADE_COMPARE(c, (Vector2ui{3526872522, 2})); + + constexpr Vector2ui ca{3526872522, 2}; + constexpr VkExtent2D cb(ca); + constexpr Vector2ui cc(cb); + CORRADE_COMPARE(cb.width, 3526872522); + CORRADE_COMPARE(cb.height, 2); + CORRADE_COMPARE(cc, (Vector2ui{3526872522, 2})); +} + +void IntegrationTest::vkExtent3D() { + Vector3ui a{3, 3526872522, 1}; + VkExtent3D b(a); + Vector3ui c(b); + CORRADE_COMPARE(b.width, 3); + CORRADE_COMPARE(b.height, 3526872522); + CORRADE_COMPARE(b.depth, 1); + CORRADE_COMPARE(c, (Vector3ui{3, 3526872522, 1})); + + constexpr Vector3ui ca{3, 3526872522, 1}; + constexpr VkExtent3D cb(ca); + constexpr Vector3ui cc(cb); + CORRADE_COMPARE(cb.width, 3); + CORRADE_COMPARE(cb.height, 3526872522); + CORRADE_COMPARE(cb.depth, 1); + CORRADE_COMPARE(cc, (Vector3ui{3, 3526872522, 1})); +} + +void IntegrationTest::vkExtent2DSigned() { + Vector2i a{1526872125, 2}; + VkExtent2D b(a); + Vector2i c(b); + CORRADE_COMPARE(b.width, 1526872125); + CORRADE_COMPARE(b.height, 2); + CORRADE_COMPARE(c, (Vector2i{1526872125, 2})); + + constexpr Vector2i ca{1526872125, 2}; + constexpr VkExtent2D cb(ca); + constexpr Vector2i cc(cb); + CORRADE_COMPARE(cb.width, 1526872125); + CORRADE_COMPARE(cb.height, 2); + CORRADE_COMPARE(cc, (Vector2i{1526872125, 2})); +} + +void IntegrationTest::vkExtent3DSigned() { + Vector3i a{3, 2, 1526872125}; + VkExtent3D b(a); + Vector3i c(b); + CORRADE_COMPARE(b.width, 3); + CORRADE_COMPARE(b.height, 2); + CORRADE_COMPARE(b.depth, 1526872125); + CORRADE_COMPARE(c, (Vector3i{3, 2, 1526872125})); + + constexpr Vector3i ca{3, 2, 1526872125}; + constexpr VkExtent3D cb(ca); + constexpr Vector3i cc(cb); + CORRADE_COMPARE(cb.width, 3); + CORRADE_COMPARE(cb.height, 2); + CORRADE_COMPARE(cb.depth, 1526872125); + CORRADE_COMPARE(cc, (Vector3i{3, 2, 1526872125})); +} + +void IntegrationTest::vkClearColorValueFloat() { + Color4 a{0.3f, 0.7f, 0.1f, 0.88f}; + VkClearColorValue b(a); + Color4 c(b); + CORRADE_COMPARE(b.float32[0], 0.3f); + CORRADE_COMPARE(b.float32[1], 0.7f); + CORRADE_COMPARE(b.float32[2], 0.1f); + CORRADE_COMPARE(b.float32[3], 0.88f); + CORRADE_COMPARE(c, (Color4{0.3f, 0.7f, 0.1f, 0.88f})); + + /** @todo test constexpr once/if possible */ +} + +void IntegrationTest::vkClearColorValueSigned() { + Vector4i a{13, -42, 1337, 1526872125}; + VkClearColorValue b(a); + Vector4i c(b); + CORRADE_COMPARE(b.int32[0], 13); + CORRADE_COMPARE(b.int32[1], -42); + CORRADE_COMPARE(b.int32[2], 1337); + CORRADE_COMPARE(b.int32[3], 1526872125); + CORRADE_COMPARE(c, (Vector4i{13, -42, 1337, 1526872125})); + + /** @todo test constexpr once/if possible */ +} + +void IntegrationTest::vkClearColorValueUnsigned() { + Vector4ui a{13, 42, 1337, 3526872522}; + VkClearColorValue b(a); + Vector4ui c(b); + CORRADE_COMPARE(b.uint32[0], 13); + CORRADE_COMPARE(b.uint32[1], 42); + CORRADE_COMPARE(b.uint32[2], 1337); + CORRADE_COMPARE(b.uint32[3], 3526872522); + CORRADE_COMPARE(c, (Vector4ui{13, 42, 1337, 3526872522})); + + /** @todo test constexpr once/if possible */ +} + +void IntegrationTest::vkClearColorValue3() { + Color3 a{0.3f, 0.7f, 0.88f}; + VkClearColorValue b(a); + CORRADE_COMPARE(b.float32[0], 0.3f); + CORRADE_COMPARE(b.float32[1], 0.7f); + CORRADE_COMPARE(b.float32[2], 0.88f); + CORRADE_COMPARE(b.float32[3], 1.0f); + + /** @todo test constexpr once/if possible */ + + /* Conversion the ohter way not allowed */ + CORRADE_VERIFY((std::is_constructible::value)); + CORRADE_VERIFY(!(std::is_constructible::value)); +} + +void IntegrationTest::vkViewport() { + Range3D a = Range3D::fromSize({3.0f, 2.5f, -1.0f}, {2.7f, 0.3f, 1.1f}); + VkViewport b(a); + Range3D c(b); + CORRADE_COMPARE(b.x, 3.0f); + CORRADE_COMPARE(b.y, 2.5f); + CORRADE_COMPARE(b.minDepth, -1.0f); + CORRADE_COMPARE(b.width, 2.7f); + CORRADE_COMPARE(b.height, 0.3f); + CORRADE_COMPARE(b.maxDepth, 0.1f); + CORRADE_COMPARE(c, Range3D::fromSize({3.0f, 2.5f, -1.0f}, {2.7f, 0.3f, 1.1f})); + + constexpr Range3D ca{{3.0f, 2.5f, -1.0f}, {5.7f, 2.8f, 0.1f}}; + constexpr VkViewport cb(ca); + constexpr Range3D cc(cb); + CORRADE_COMPARE(cb.x, 3.0f); + CORRADE_COMPARE(cb.y, 2.5f); + CORRADE_COMPARE(cb.minDepth, -1.0f); + CORRADE_COMPARE(cb.width, 2.7f); + CORRADE_COMPARE(cb.height, 0.3f); + CORRADE_COMPARE(cb.maxDepth, 0.1f); + CORRADE_COMPARE(cc, Range3D::fromSize({3.0f, 2.5f, -1.0f}, {2.7f, 0.3f, 1.1f})); +} + +void IntegrationTest::vkRect2D() { + Range2Di a = Range2Di::fromSize({3, -2}, {23, 45}); + VkRect2D b(a); + Range2Di c(b); + CORRADE_COMPARE(b.offset.x, 3); + CORRADE_COMPARE(b.offset.y, -2); + CORRADE_COMPARE(b.extent.width, 23); + CORRADE_COMPARE(b.extent.height, 45); + CORRADE_COMPARE(c, Range2Di::fromSize({3, -2}, {23, 45})); + + constexpr Range2Di ca{{3, -2}, {26, 43}}; + constexpr VkRect2D cb(ca); + constexpr Range2Di cc(cb); + CORRADE_COMPARE(cb.offset.x, 3); + CORRADE_COMPARE(cb.offset.y, -2); + CORRADE_COMPARE(cb.extent.width, 23); + CORRADE_COMPARE(cb.extent.height, 45); + CORRADE_COMPARE(cc, Range2Di::fromSize({3, -2}, {23, 45})); +} + +void IntegrationTest::vkClearRect() { + Range3Di a = Range3Di::fromSize({3, -2, 1}, {23, 45, 7}); + VkClearRect b(a); + Range3Di c(b); + CORRADE_COMPARE(b.rect.offset.x, 3); + CORRADE_COMPARE(b.rect.offset.y, -2); + CORRADE_COMPARE(b.baseArrayLayer, 1); + CORRADE_COMPARE(b.rect.extent.width, 23); + CORRADE_COMPARE(b.rect.extent.height, 45); + CORRADE_COMPARE(b.layerCount, 7); + CORRADE_COMPARE(c, Range3Di::fromSize({3, -2, 1}, {23, 45, 7})); + + constexpr Range3Di ca{{3, -2, 1}, {26, 43, 8}}; + constexpr VkClearRect cb(ca); + constexpr Range3Di cc(cb); + CORRADE_COMPARE(cb.rect.offset.x, 3); + CORRADE_COMPARE(cb.rect.offset.y, -2); + CORRADE_COMPARE(cb.baseArrayLayer, 1); + CORRADE_COMPARE(cb.rect.extent.width, 23); + CORRADE_COMPARE(cb.rect.extent.height, 45); + CORRADE_COMPARE(cb.layerCount, 7); + CORRADE_COMPARE(cc, Range3Di::fromSize({3, -2, 1}, {23, 45, 7})); +} + +}}} + +CORRADE_TEST_MAIN(Magnum::Vk::Test::IntegrationTest)