From 9ce36aa668d8a5c0f5e835984cf1ddf87f8c6cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 8 Feb 2021 17:07:41 +0100 Subject: [PATCH] Vk: rvalue overloads for MeshLayout setters. So it's possible to do Vk::Mesh mesh{Vk::MeshLayout{} .addBinding(...) .addAttribute(...) }; Without this, the above will result in a dangling layout reference. --- src/Magnum/Vk/MeshLayout.cpp | 24 ++++++++++++++++++++---- src/Magnum/Vk/MeshLayout.h | 16 ++++++++++++---- src/Magnum/Vk/Test/MeshLayoutTest.cpp | 17 +++++++++++++++++ 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/Magnum/Vk/MeshLayout.cpp b/src/Magnum/Vk/MeshLayout.cpp index 5d49267ca..ac485c340 100644 --- a/src/Magnum/Vk/MeshLayout.cpp +++ b/src/Magnum/Vk/MeshLayout.cpp @@ -172,7 +172,7 @@ bool MeshLayout::operator==(const MeshLayout& other) const { #undef _c } -MeshLayout& MeshLayout::addBinding(const UnsignedInt binding, const UnsignedInt stride) { +MeshLayout& MeshLayout::addBinding(const UnsignedInt binding, const UnsignedInt stride) & { if(!_state) _state.emplace(); /* Ensure order for efficient comparisons */ @@ -190,7 +190,11 @@ MeshLayout& MeshLayout::addBinding(const UnsignedInt binding, const UnsignedInt return *this; } -MeshLayout& MeshLayout::addInstancedBinding(const UnsignedInt binding, const UnsignedInt stride, const UnsignedInt divisor) { +MeshLayout&& MeshLayout::addBinding(const UnsignedInt binding, const UnsignedInt stride) && { + return std::move(addBinding(binding, stride)); +} + +MeshLayout& MeshLayout::addInstancedBinding(const UnsignedInt binding, const UnsignedInt stride, const UnsignedInt divisor) & { if(!_state) _state.emplace(); /* Ensure order for efficient comparisons */ @@ -221,7 +225,11 @@ MeshLayout& MeshLayout::addInstancedBinding(const UnsignedInt binding, const Uns return *this; } -MeshLayout& MeshLayout::addAttribute(const UnsignedInt location, const UnsignedInt binding, const VertexFormat format, const UnsignedInt offset) { +MeshLayout&& MeshLayout::addInstancedBinding(const UnsignedInt binding, const UnsignedInt stride, const UnsignedInt divisor) && { + return std::move(addInstancedBinding(binding, stride, divisor)); +} + +MeshLayout& MeshLayout::addAttribute(const UnsignedInt location, const UnsignedInt binding, const VertexFormat format, const UnsignedInt offset) & { if(!_state) _state.emplace(); /* Ensure order for efficient comparisons */ @@ -240,10 +248,18 @@ MeshLayout& MeshLayout::addAttribute(const UnsignedInt location, const UnsignedI return *this; } -MeshLayout& MeshLayout::addAttribute(const UnsignedInt location, const UnsignedInt binding, const Magnum::VertexFormat format, const UnsignedInt offset) { +MeshLayout&& MeshLayout::addAttribute(const UnsignedInt location, const UnsignedInt binding, const VertexFormat format, const UnsignedInt offset) && { + return std::move(addAttribute(location, binding, format, offset)); +} + +MeshLayout& MeshLayout::addAttribute(const UnsignedInt location, const UnsignedInt binding, const Magnum::VertexFormat format, const UnsignedInt offset) & { return addAttribute(location, binding, vertexFormat(format), offset); } +MeshLayout&& MeshLayout::addAttribute(const UnsignedInt location, const UnsignedInt binding, const Magnum::VertexFormat format, const UnsignedInt offset) && { + return std::move(addAttribute(location, binding, format, offset)); +} + Debug& operator<<(Debug& debug, const MeshPrimitive value) { debug << "Vk::MeshPrimitive" << Debug::nospace; diff --git a/src/Magnum/Vk/MeshLayout.h b/src/Magnum/Vk/MeshLayout.h index 86218823e..d27ee00d4 100644 --- a/src/Magnum/Vk/MeshLayout.h +++ b/src/Magnum/Vk/MeshLayout.h @@ -307,7 +307,9 @@ class MAGNUM_VK_EXPORT MeshLayout { * * @see @ref addInstancedBinding() */ - MeshLayout& addBinding(UnsignedInt binding, UnsignedInt stride); + MeshLayout& addBinding(UnsignedInt binding, UnsignedInt stride) &; + /** @overload */ + MeshLayout&& addBinding(UnsignedInt binding, UnsignedInt stride) &&; /** * @brief Add an instanced buffer binding @@ -344,7 +346,9 @@ class MAGNUM_VK_EXPORT MeshLayout { * @requires_vk_feature @ref DeviceFeature::VertexAttributeInstanceRateZeroDivisor * if @p divisor is `0` */ - MeshLayout& addInstancedBinding(UnsignedInt binding, UnsignedInt stride, UnsignedInt divisor = 1); + MeshLayout& addInstancedBinding(UnsignedInt binding, UnsignedInt stride, UnsignedInt divisor = 1) &; + /** @overload */ + MeshLayout&& addInstancedBinding(UnsignedInt binding, UnsignedInt stride, UnsignedInt divisor = 1) &&; /** * @brief Add an attribute @@ -368,9 +372,13 @@ class MAGNUM_VK_EXPORT MeshLayout { * - `format` * - `offset` */ - MeshLayout& addAttribute(UnsignedInt location, UnsignedInt binding, VertexFormat format, UnsignedInt offset); + MeshLayout& addAttribute(UnsignedInt location, UnsignedInt binding, VertexFormat format, UnsignedInt offset) &; + /** @overload */ + MeshLayout&& addAttribute(UnsignedInt location, UnsignedInt binding, VertexFormat format, UnsignedInt offset) &&; + /** @overload */ + MeshLayout& addAttribute(UnsignedInt location, UnsignedInt binding, Magnum::VertexFormat format, UnsignedInt offset) &; /** @overload */ - MeshLayout& addAttribute(UnsignedInt location, UnsignedInt binding, Magnum::VertexFormat format, UnsignedInt offset); + MeshLayout&& addAttribute(UnsignedInt location, UnsignedInt binding, Magnum::VertexFormat format, UnsignedInt offset) &&; /** @brief Underlying @type_vk{PipelineVertexInputStateCreateInfo} structure */ VkPipelineVertexInputStateCreateInfo& vkPipelineVertexInputStateCreateInfo() { diff --git a/src/Magnum/Vk/Test/MeshLayoutTest.cpp b/src/Magnum/Vk/Test/MeshLayoutTest.cpp index d7634e9d1..1520926d7 100644 --- a/src/Magnum/Vk/Test/MeshLayoutTest.cpp +++ b/src/Magnum/Vk/Test/MeshLayoutTest.cpp @@ -57,6 +57,8 @@ struct MeshLayoutTest: TestSuite::Tester { template void addAttribute(); void addAttributeWrongOrder(); + void rvalue(); + void compare(); void compareExternalPointers(); @@ -84,6 +86,8 @@ MeshLayoutTest::MeshLayoutTest() { &MeshLayoutTest::addAttribute, &MeshLayoutTest::addAttributeWrongOrder, + &MeshLayoutTest::rvalue, + &MeshLayoutTest::compare, &MeshLayoutTest::compareExternalPointers, @@ -383,6 +387,19 @@ void MeshLayoutTest::addAttributeWrongOrder() { "Vk::MeshLayout::addAttribute(): location 5 can't be ordered after 5\n"); } +void MeshLayoutTest::rvalue() { + MeshLayout&& layout = MeshLayout{MeshPrimitive::TriangleFan} + .addBinding(0, 37) + .addInstancedBinding(1, 26) + .addAttribute(0, 0, VertexFormat{}, 0) + .addAttribute(1, 1, Magnum::VertexFormat::Vector2, 0); + + /* Just to test something, main point is that the above compiles, links and + returns a &&. Can't test anything related to the contents because the + destructor gets called at the end of the expression. */ + CORRADE_VERIFY(&layout); +} + void MeshLayoutTest::compare() { MeshLayout emptyTriangles1{MeshPrimitive::Triangles}; MeshLayout emptyTriangles2{MeshPrimitive::Triangles};