diff --git a/src/Magnum/Trade/MeshData.h b/src/Magnum/Trade/MeshData.h index f870222a2..ece42a4f1 100644 --- a/src/Magnum/Trade/MeshData.h +++ b/src/Magnum/Trade/MeshData.h @@ -448,11 +448,12 @@ class MAGNUM_TRADE_EXPORT MeshAttributeData { * @param arraySize Array size. Use @cpp 0 @ce for non-array * attributes. * - * Expects that @p data stride fits into a signed 16-bit value, and for - * builtin attributes that @p format corresponds to @p name, - * @p arraySize is either zero for non-array attributes or non-zero for - * array attributes. The stride can be zero or negative, but note that - * such data layouts are not commonly supported by GPU APIs. + * Expects that @p data stride fits into a signed 16-bit value, that + * vertex count fits into 32 bits, and for builtin attributes that + * @p format corresponds to @p name, @p arraySize is either zero for + * non-array attributes or non-zero for array attributes. The stride + * can be zero or negative, but note that such data layouts are not + * commonly supported by GPU APIs. */ explicit MeshAttributeData(MeshAttribute name, VertexFormat format, const Containers::StridedArrayView1D& data, UnsignedShort arraySize = 0) noexcept; @@ -2429,7 +2430,12 @@ constexpr MeshAttributeData::MeshAttributeData(std::nullptr_t, const MeshAttribu _format{format}, _name{(CORRADE_CONSTEXPR_ASSERT(Implementation::isVertexFormatCompatibleWithAttribute(name, format), "Trade::MeshAttributeData:" << format << "is not a valid format for" << name), name)}, - _isOffsetOnly{false}, _vertexCount{UnsignedInt(data.size())}, + _isOffsetOnly{false}, + _vertexCount{( + #ifndef CORRADE_TARGET_32BIT + CORRADE_CONSTEXPR_ASSERT(data.size() <= 0xffffffffu, "Trade::MeshAttributeData: expected vertex count to fit into 32 bits but got" << data.size()), + #endif + UnsignedInt(data.size()))}, _stride{(CORRADE_CONSTEXPR_ASSERT(data.stride() >= -32768 && data.stride() <= 32767, "Trade::MeshAttributeData: expected stride to fit into 16 bits but got" << data.stride()), Short(data.stride()))}, diff --git a/src/Magnum/Trade/Test/MeshDataTest.cpp b/src/Magnum/Trade/Test/MeshDataTest.cpp index ba042b7a2..67e882938 100644 --- a/src/Magnum/Trade/Test/MeshDataTest.cpp +++ b/src/Magnum/Trade/Test/MeshDataTest.cpp @@ -75,6 +75,9 @@ struct MeshDataTest: TestSuite::Tester { void constructAttributeOffsetOnly(); void constructAttributeImplementationSpecificFormat(); void constructAttributeWrongFormat(); + #ifndef CORRADE_TARGET_32BIT + void constructAttributeWrongSize(); + #endif void constructAttributeWrongStride(); void constructAttributeWrongDataAccess(); void constructAttributeOnlyArrayAllowed(); @@ -262,6 +265,9 @@ MeshDataTest::MeshDataTest() { &MeshDataTest::constructAttributeOffsetOnly, &MeshDataTest::constructAttributeImplementationSpecificFormat, &MeshDataTest::constructAttributeWrongFormat, + #ifndef CORRADE_TARGET_32BIT + &MeshDataTest::constructAttributeWrongSize, + #endif &MeshDataTest::constructAttributeWrongStride, &MeshDataTest::constructAttributeWrongDataAccess, &MeshDataTest::constructAttributeOnlyArrayAllowed, @@ -992,6 +998,23 @@ void MeshDataTest::constructAttributeWrongFormat() { "Trade::MeshAttributeData: VertexFormat::Vector2 is not a valid format for Trade::MeshAttribute::Color\n"); } +#ifndef CORRADE_TARGET_32BIT +void MeshDataTest::constructAttributeWrongSize() { + CORRADE_SKIP_IF_NO_ASSERT(); + + /* This should be fine */ + MeshAttributeData{MeshAttribute::Position, Containers::ArrayView{nullptr, 0xffffffffu}}; + + std::ostringstream out; + Error redirectError{&out}; + MeshAttributeData{MeshAttribute::Position, Containers::ArrayView{nullptr, 0x100000000ull}}; + /* The offset-only constructors takes the count as an UnsignedInt already, + nothing to check there */ + CORRADE_COMPARE(out.str(), + "Trade::MeshAttributeData: expected vertex count to fit into 32 bits but got 4294967296\n"); +} +#endif + void MeshDataTest::constructAttributeWrongStride() { CORRADE_SKIP_IF_NO_ASSERT();