Browse Source

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.
pull/495/head
Vladimír Vondruš 5 years ago
parent
commit
9ce36aa668
  1. 24
      src/Magnum/Vk/MeshLayout.cpp
  2. 16
      src/Magnum/Vk/MeshLayout.h
  3. 17
      src/Magnum/Vk/Test/MeshLayoutTest.cpp

24
src/Magnum/Vk/MeshLayout.cpp

@ -172,7 +172,7 @@ bool MeshLayout::operator==(const MeshLayout& other) const {
#undef _c #undef _c
} }
MeshLayout& MeshLayout::addBinding(const UnsignedInt binding, const UnsignedInt stride) { MeshLayout& MeshLayout::addBinding(const UnsignedInt binding, const UnsignedInt stride) & {
if(!_state) _state.emplace(); if(!_state) _state.emplace();
/* Ensure order for efficient comparisons */ /* Ensure order for efficient comparisons */
@ -190,7 +190,11 @@ MeshLayout& MeshLayout::addBinding(const UnsignedInt binding, const UnsignedInt
return *this; 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(); if(!_state) _state.emplace();
/* Ensure order for efficient comparisons */ /* Ensure order for efficient comparisons */
@ -221,7 +225,11 @@ MeshLayout& MeshLayout::addInstancedBinding(const UnsignedInt binding, const Uns
return *this; 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(); if(!_state) _state.emplace();
/* Ensure order for efficient comparisons */ /* Ensure order for efficient comparisons */
@ -240,10 +248,18 @@ MeshLayout& MeshLayout::addAttribute(const UnsignedInt location, const UnsignedI
return *this; 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); 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& operator<<(Debug& debug, const MeshPrimitive value) {
debug << "Vk::MeshPrimitive" << Debug::nospace; debug << "Vk::MeshPrimitive" << Debug::nospace;

16
src/Magnum/Vk/MeshLayout.h

@ -307,7 +307,9 @@ class MAGNUM_VK_EXPORT MeshLayout {
* *
* @see @ref addInstancedBinding() * @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 * @brief Add an instanced buffer binding
@ -344,7 +346,9 @@ class MAGNUM_VK_EXPORT MeshLayout {
* @requires_vk_feature @ref DeviceFeature::VertexAttributeInstanceRateZeroDivisor * @requires_vk_feature @ref DeviceFeature::VertexAttributeInstanceRateZeroDivisor
* if @p divisor is `0` * 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 * @brief Add an attribute
@ -368,9 +372,13 @@ class MAGNUM_VK_EXPORT MeshLayout {
* - `format` * - `format`
* - `offset` * - `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 */ /** @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 */ /** @brief Underlying @type_vk{PipelineVertexInputStateCreateInfo} structure */
VkPipelineVertexInputStateCreateInfo& vkPipelineVertexInputStateCreateInfo() { VkPipelineVertexInputStateCreateInfo& vkPipelineVertexInputStateCreateInfo() {

17
src/Magnum/Vk/Test/MeshLayoutTest.cpp

@ -57,6 +57,8 @@ struct MeshLayoutTest: TestSuite::Tester {
template<class T> void addAttribute(); template<class T> void addAttribute();
void addAttributeWrongOrder(); void addAttributeWrongOrder();
void rvalue();
void compare(); void compare();
void compareExternalPointers(); void compareExternalPointers();
@ -84,6 +86,8 @@ MeshLayoutTest::MeshLayoutTest() {
&MeshLayoutTest::addAttribute<Magnum::VertexFormat>, &MeshLayoutTest::addAttribute<Magnum::VertexFormat>,
&MeshLayoutTest::addAttributeWrongOrder, &MeshLayoutTest::addAttributeWrongOrder,
&MeshLayoutTest::rvalue,
&MeshLayoutTest::compare, &MeshLayoutTest::compare,
&MeshLayoutTest::compareExternalPointers, &MeshLayoutTest::compareExternalPointers,
@ -383,6 +387,19 @@ void MeshLayoutTest::addAttributeWrongOrder() {
"Vk::MeshLayout::addAttribute(): location 5 can't be ordered after 5\n"); "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() { void MeshLayoutTest::compare() {
MeshLayout emptyTriangles1{MeshPrimitive::Triangles}; MeshLayout emptyTriangles1{MeshPrimitive::Triangles};
MeshLayout emptyTriangles2{MeshPrimitive::Triangles}; MeshLayout emptyTriangles2{MeshPrimitive::Triangles};

Loading…
Cancel
Save