Browse Source

Add an ability to store implementation-specific values in MeshIndexType.

The type is now extended to 32 bits. In the GL and Vk libraries it means
one can now do things like

    MeshIndexType type = meshIndexTypeWrap(GL_UNSIGNED_BYTE);

and passing that to GL::Mesh or Vk::Mesh will cause it to use the value
directly, instead of doing a mapping from a generic type. The *real* use
case for this is however to allow custom index buffer representations in
Trade::MeshData. Support for that will be hooked up in the following
commit.
pull/547/head
Vladimír Vondruš 4 years ago
parent
commit
a35a3ec271
  1. 3
      doc/changelog.dox
  2. 3
      src/Magnum/GL/Mesh.cpp
  3. 34
      src/Magnum/GL/Mesh.h
  4. 7
      src/Magnum/GL/Test/MeshTest.cpp
  5. 2
      src/Magnum/Magnum.h
  6. 9
      src/Magnum/Mesh.cpp
  7. 52
      src/Magnum/Mesh.h
  8. 77
      src/Magnum/Test/MeshTest.cpp
  9. 1
      src/Magnum/Trade/MeshData.h
  10. 3
      src/Magnum/Vk/Mesh.cpp
  11. 26
      src/Magnum/Vk/Mesh.h
  12. 7
      src/Magnum/Vk/Test/MeshTest.cpp

3
doc/changelog.dox

@ -285,6 +285,9 @@ See also:
- Added @ref MeshPrimitive::Meshlets as a placeholder for future meshlet - Added @ref MeshPrimitive::Meshlets as a placeholder for future meshlet
support in @ref Trade::MeshData support in @ref Trade::MeshData
- @ref MeshIndexType was enlarged to 32 bits and can now wrap
implementation-specific values similar to @ref PixelFormat,
@ref CompressedPixelFormat, @ref VertexFormat and @ref MeshPrimitive
@subsubsection changelog-latest-changes-debugtools DebugTools library @subsubsection changelog-latest-changes-debugtools DebugTools library

3
src/Magnum/GL/Mesh.cpp

@ -96,6 +96,9 @@ MeshPrimitive meshPrimitive(const Magnum::MeshPrimitive primitive) {
} }
MeshIndexType meshIndexType(const Magnum::MeshIndexType type) { MeshIndexType meshIndexType(const Magnum::MeshIndexType type) {
if(isMeshIndexTypeImplementationSpecific(type))
return meshIndexTypeUnwrap<GL::MeshIndexType>(type);
CORRADE_ASSERT(UnsignedInt(type) - 1 < Containers::arraySize(IndexTypeMapping), CORRADE_ASSERT(UnsignedInt(type) - 1 < Containers::arraySize(IndexTypeMapping),
"GL::meshIndexType(): invalid type" << type, {}); "GL::meshIndexType(): invalid type" << type, {});
return IndexTypeMapping[UnsignedInt(type) - 1]; return IndexTypeMapping[UnsignedInt(type) - 1];

34
src/Magnum/GL/Mesh.h

@ -197,6 +197,11 @@ enum class MeshIndexType: GLenum {
/** /**
@brief Convert generic mesh index type to OpenGL mesh index type @brief Convert generic mesh index type to OpenGL mesh index type
In case @ref isMeshIndexTypeImplementationSpecific() returns @cpp false @ce for
@p type, maps it to a corresponding OpenGL type. In case
@ref isMeshIndexTypeImplementationSpecific() returns @cpp true @ce, assumes
@p type stores a Vulkan-specific format and returns @ref meshIndexTypeUnwrap()
cast to @ref MeshIndexType.
@see @ref meshPrimitive(), @ref meshIndexTypeSize() @see @ref meshPrimitive(), @ref meshIndexTypeSize()
*/ */
MAGNUM_GL_EXPORT MeshIndexType meshIndexType(Magnum::MeshIndexType type); MAGNUM_GL_EXPORT MeshIndexType meshIndexType(Magnum::MeshIndexType type);
@ -1029,7 +1034,14 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
return setIndexBuffer(buffer, offset, type, 0, 0); return setIndexBuffer(buffer, offset, type, 0, 0);
} }
/** @overload */ /** @overload
* @brief Set index buffer with a generic index type
*
* Note that implementation-specific values are passed as-is with
* @ref meshIndexTypeUnwrap(). It's the user responsibility to ensure
* an implementation-specific value actually represents a valid OpenGL
* index type.
*/
Mesh& setIndexBuffer(Buffer& buffer, GLintptr offset, Magnum::MeshIndexType type) { Mesh& setIndexBuffer(Buffer& buffer, GLintptr offset, Magnum::MeshIndexType type) {
return setIndexBuffer(buffer, offset, meshIndexType(type), 0, 0); return setIndexBuffer(buffer, offset, meshIndexType(type), 0, 0);
} }
@ -1043,7 +1055,14 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
*/ */
Mesh& setIndexBuffer(Buffer&& buffer, GLintptr offset, MeshIndexType type, UnsignedInt start, UnsignedInt end); Mesh& setIndexBuffer(Buffer&& buffer, GLintptr offset, MeshIndexType type, UnsignedInt start, UnsignedInt end);
/** @overload */ /** @overload
* @brief Set index buffer with a generic index type and ownership transfer
*
* Note that implementation-specific values are passed as-is with
* @ref meshIndexTypeUnwrap(). It's the user responsibility to ensure
* an implementation-specific value actually represents a valid OpenGL
* index type.
*/
Mesh& setIndexBuffer(Buffer&& buffer, GLintptr offset, Magnum::MeshIndexType type, UnsignedInt start, UnsignedInt end) { Mesh& setIndexBuffer(Buffer&& buffer, GLintptr offset, Magnum::MeshIndexType type, UnsignedInt start, UnsignedInt end) {
return setIndexBuffer(std::move(buffer), offset, meshIndexType(type), start, end); return setIndexBuffer(std::move(buffer), offset, meshIndexType(type), start, end);
} }
@ -1058,9 +1077,18 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
Mesh& setIndexBuffer(Buffer&& buffer, GLintptr offset, MeshIndexType type) { Mesh& setIndexBuffer(Buffer&& buffer, GLintptr offset, MeshIndexType type) {
return setIndexBuffer(std::move(buffer), offset, type, 0, 0); return setIndexBuffer(std::move(buffer), offset, type, 0, 0);
} }
/** @overload
* @brief Set index buffer with a generic index type and ownership transfer
*
* Note that implementation-specific values are passed as-is with
* @ref meshIndexTypeUnwrap(). It's the user responsibility to ensure
* an implementation-specific value actually represents a valid OpenGL
* index type.
*/
Mesh& setIndexBuffer(Buffer&& buffer, GLintptr offset, Magnum::MeshIndexType type) { Mesh& setIndexBuffer(Buffer&& buffer, GLintptr offset, Magnum::MeshIndexType type) {
return setIndexBuffer(std::move(buffer), offset, meshIndexType(type), 0, 0); return setIndexBuffer(std::move(buffer), offset, meshIndexType(type), 0, 0);
} /**< @overload */ }
#ifdef MAGNUM_BUILD_DEPRECATED #ifdef MAGNUM_BUILD_DEPRECATED
/** /**

7
src/Magnum/GL/Test/MeshTest.cpp

@ -55,6 +55,7 @@ struct MeshTest: TestSuite::Tester {
void mapPrimitiveInvalid(); void mapPrimitiveInvalid();
void mapIndexType(); void mapIndexType();
void mapIndexTypeImplementationSpecific();
void mapIndexTypeInvalid(); void mapIndexTypeInvalid();
void debugPrimitive(); void debugPrimitive();
@ -77,6 +78,7 @@ MeshTest::MeshTest() {
&MeshTest::mapPrimitiveInvalid, &MeshTest::mapPrimitiveInvalid,
&MeshTest::mapIndexType, &MeshTest::mapIndexType,
&MeshTest::mapIndexTypeImplementationSpecific,
&MeshTest::mapIndexTypeInvalid, &MeshTest::mapIndexTypeInvalid,
&MeshTest::debugPrimitive, &MeshTest::debugPrimitive,
@ -252,6 +254,11 @@ void MeshTest::mapIndexType() {
} }
} }
void MeshTest::mapIndexTypeImplementationSpecific() {
CORRADE_COMPARE(meshIndexType(meshIndexTypeWrap(GL_UNSIGNED_BYTE)),
MeshIndexType::UnsignedByte);
}
void MeshTest::mapIndexTypeInvalid() { void MeshTest::mapIndexTypeInvalid() {
#ifdef CORRADE_NO_ASSERT #ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");

2
src/Magnum/Magnum.h

@ -1257,7 +1257,7 @@ typedef BasicMutableCompressedImageView<2> MutableCompressedImageView2D;
typedef BasicMutableCompressedImageView<3> MutableCompressedImageView3D; typedef BasicMutableCompressedImageView<3> MutableCompressedImageView3D;
enum class MeshPrimitive: UnsignedInt; enum class MeshPrimitive: UnsignedInt;
enum class MeshIndexType: UnsignedByte; enum class MeshIndexType: UnsignedInt;
enum class VertexFormat: UnsignedInt; enum class VertexFormat: UnsignedInt;
enum class PixelFormat: UnsignedInt; enum class PixelFormat: UnsignedInt;

9
src/Magnum/Mesh.cpp

@ -70,6 +70,10 @@ constexpr const char* MeshIndexTypeNames[] {
Debug& operator<<(Debug& debug, const MeshIndexType value) { Debug& operator<<(Debug& debug, const MeshIndexType value) {
debug << "MeshIndexType" << Debug::nospace; debug << "MeshIndexType" << Debug::nospace;
if(isMeshIndexTypeImplementationSpecific(value)) {
return debug << "::ImplementationSpecific(" << Debug::nospace << reinterpret_cast<void*>(meshIndexTypeUnwrap(value)) << Debug::nospace << ")";
}
if(UnsignedInt(value) - 1 < Containers::arraySize(MeshIndexTypeNames)) { if(UnsignedInt(value) - 1 < Containers::arraySize(MeshIndexTypeNames)) {
return debug << "::" << Debug::nospace << MeshIndexTypeNames[UnsignedInt(value) - 1]; return debug << "::" << Debug::nospace << MeshIndexTypeNames[UnsignedInt(value) - 1];
} }
@ -78,7 +82,10 @@ Debug& operator<<(Debug& debug, const MeshIndexType value) {
} }
#endif #endif
UnsignedInt meshIndexTypeSize(MeshIndexType type) { UnsignedInt meshIndexTypeSize(const MeshIndexType type) {
CORRADE_ASSERT(!isMeshIndexTypeImplementationSpecific(type),
"meshIndexTypeSize(): can't determine size of an implementation-specific type" << reinterpret_cast<void*>(meshIndexTypeUnwrap(type)), {});
switch(type) { switch(type) {
case MeshIndexType::UnsignedByte: return 1; case MeshIndexType::UnsignedByte: return 1;
case MeshIndexType::UnsignedShort: return 2; case MeshIndexType::UnsignedShort: return 2;

52
src/Magnum/Mesh.h

@ -246,6 +246,12 @@ template<class T = UnsignedInt> constexpr T meshPrimitiveUnwrap(MeshPrimitive pr
/** /**
@brief Mesh index type @brief Mesh index type
A counterpart to @ref VertexFormat describing a mesh index type. Can act also
as a wrapper for implementation-specific mesh index type valueus uing
@ref meshIndexTypeWrap() and @ref meshIndexTypeUnwrap(). Distinction between
generic and implementation-specific types can be done using
@ref isMeshIndexTypeImplementationSpecific().
In case of OpenGL, corresponds to @ref GL::MeshIndexType and is convertible to In case of OpenGL, corresponds to @ref GL::MeshIndexType and is convertible to
it using @ref GL::meshIndexType(). See documentation of each value for more it using @ref GL::meshIndexType(). See documentation of each value for more
information about the mapping. information about the mapping.
@ -259,7 +265,7 @@ for Metal, corresponds to @m_class{m-doc-external} [MTLIndexType](https://develo
See documentation of each value for more information about the mapping. See documentation of each value for more information about the mapping.
@see @ref meshIndexTypeSize() @see @ref meshIndexTypeSize()
*/ */
enum class MeshIndexType: UnsignedByte { enum class MeshIndexType: UnsignedInt {
/* Zero reserved for an invalid type (but not being a named value) */ /* Zero reserved for an invalid type (but not being a named value) */
/** /**
@ -299,6 +305,50 @@ enum class MeshIndexType: UnsignedByte {
/** @debugoperatorenum{MeshIndexType} */ /** @debugoperatorenum{MeshIndexType} */
MAGNUM_EXPORT Debug& operator<<(Debug& debug, MeshIndexType value); MAGNUM_EXPORT Debug& operator<<(Debug& debug, MeshIndexType value);
/**
@brief Whether a @ref MeshIndexType value wraps an implementation-specific identifier
@m_since_latest
Returns @cpp true @ce if value of @p type has its highest bit set,
@cpp false @ce otherwise. Use @ref meshIndexTypeWrap() and
@ref meshIndexTypeUnwrap() to wrap/unwrap an implementation-specific
indentifier to/from @ref MeshIndexType.
*/
constexpr bool isMeshIndexTypeImplementationSpecific(MeshIndexType type) {
return UnsignedInt(type) & (1u << 31);
}
/**
@brief Wrap an implementation-specific mesh index type identifier in @ref MeshIndexType
@m_since_latest
Sets the highest bit on @p implementationSpecific to mark it as
implementation-specific. Expects that @p implementationSpecific fits into the
remaining 31 bits. Use @ref meshIndexTypeUnwrap() for the inverse operation.
@see @ref isMeshIndexTypeImplementationSpecific()
*/
template<class T> constexpr MeshIndexType meshIndexTypeWrap(T implementationSpecific) {
static_assert(sizeof(T) <= 4, "types larger than 32bits are not supported");
return CORRADE_CONSTEXPR_ASSERT(!(UnsignedInt(implementationSpecific) & (1u << 31)),
"meshIndexTypeWrap(): implementation-specific value" << reinterpret_cast<void*>(implementationSpecific) << "already wrapped or too large"),
MeshIndexType((1u << 31)|UnsignedInt(implementationSpecific));
}
/**
@brief Unwrap an implementation-specific mesh index type identifier from @ref MeshIndexType
@m_since_latest
Unsets the highest bit from @p type to extract the implementation-specific
value. Expects that @p type has it set. Use @ref meshIndexTypeWrap() for
the inverse operation.
@see @ref isMeshIndexTypeImplementationSpecific()
*/
template<class T = UnsignedInt> constexpr T meshIndexTypeUnwrap(MeshIndexType type) {
return CORRADE_CONSTEXPR_ASSERT(UnsignedInt(type) & (1u << 31),
"meshIndexTypeUnwrap():" << type << "isn't a wrapped implementation-specific value"),
T(UnsignedInt(type) & ~(1u << 31));
}
/** @brief Size of given mesh index type */ /** @brief Size of given mesh index type */
MAGNUM_EXPORT UnsignedInt meshIndexTypeSize(MeshIndexType type); MAGNUM_EXPORT UnsignedInt meshIndexTypeSize(MeshIndexType type);

77
src/Magnum/Test/MeshTest.cpp

@ -44,12 +44,19 @@ struct MeshTest: TestSuite::Tester {
void primitiveUnwrapInvalid(); void primitiveUnwrapInvalid();
void indexTypeMapping(); void indexTypeMapping();
void indexTypeIsImplementationSpecific();
void indexTypeWrap();
void indexTypeWrapInvalid();
void indexTypeUnwrap();
void indexTypeUnwrapInvalid();
void indexTypeSize(); void indexTypeSize();
void indexTypeSizeInvalid(); void indexTypeSizeInvalid();
void indexTypeSizeImplementationSpecific();
void debugPrimitive(); void debugPrimitive();
void debugPrimitiveImplementationSpecific(); void debugPrimitiveImplementationSpecific();
void debugIndexType(); void debugIndexType();
void debugIndexTypeImplementationSpecific();
void configurationPrimitive(); void configurationPrimitive();
void configurationIndexType(); void configurationIndexType();
@ -64,12 +71,19 @@ MeshTest::MeshTest() {
&MeshTest::primitiveUnwrapInvalid, &MeshTest::primitiveUnwrapInvalid,
&MeshTest::indexTypeMapping, &MeshTest::indexTypeMapping,
&MeshTest::indexTypeIsImplementationSpecific,
&MeshTest::indexTypeWrap,
&MeshTest::indexTypeWrapInvalid,
&MeshTest::indexTypeUnwrap,
&MeshTest::indexTypeUnwrapInvalid,
&MeshTest::indexTypeSize, &MeshTest::indexTypeSize,
&MeshTest::indexTypeSizeInvalid, &MeshTest::indexTypeSizeInvalid,
&MeshTest::indexTypeSizeImplementationSpecific,
&MeshTest::debugPrimitive, &MeshTest::debugPrimitive,
&MeshTest::debugPrimitiveImplementationSpecific, &MeshTest::debugPrimitiveImplementationSpecific,
&MeshTest::debugIndexType, &MeshTest::debugIndexType,
&MeshTest::debugIndexTypeImplementationSpecific,
&MeshTest::configurationPrimitive, &MeshTest::configurationPrimitive,
&MeshTest::configurationIndexType}); &MeshTest::configurationIndexType});
@ -194,6 +208,47 @@ void MeshTest::indexTypeMapping() {
CORRADE_COMPARE(firstUnhandled, 0xff); CORRADE_COMPARE(firstUnhandled, 0xff);
} }
void MeshTest::indexTypeIsImplementationSpecific() {
constexpr bool a = isMeshIndexTypeImplementationSpecific(MeshIndexType::UnsignedShort);
constexpr bool b = isMeshIndexTypeImplementationSpecific(MeshIndexType(0x8000dead));
CORRADE_VERIFY(!a);
CORRADE_VERIFY(b);
}
void MeshTest::indexTypeWrap() {
constexpr MeshIndexType a = meshIndexTypeWrap(0xdead);
CORRADE_COMPARE(UnsignedInt(a), 0x8000dead);
}
void MeshTest::indexTypeWrapInvalid() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
std::ostringstream out;
Error redirectError{&out};
meshIndexTypeWrap(0xdeadbeef);
CORRADE_COMPARE(out.str(), "meshIndexTypeWrap(): implementation-specific value 0xdeadbeef already wrapped or too large\n");
}
void MeshTest::indexTypeUnwrap() {
constexpr UnsignedInt a = meshIndexTypeUnwrap(MeshIndexType(0x8000dead));
CORRADE_COMPARE(a, 0xdead);
}
void MeshTest::indexTypeUnwrapInvalid() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
std::ostringstream out;
Error redirectError{&out};
meshIndexTypeUnwrap(MeshIndexType::UnsignedInt);
CORRADE_COMPARE(out.str(), "meshIndexTypeUnwrap(): MeshIndexType::UnsignedInt isn't a wrapped implementation-specific value\n");
}
void MeshTest::indexTypeSize() { void MeshTest::indexTypeSize() {
CORRADE_COMPARE(meshIndexTypeSize(MeshIndexType::UnsignedByte), 1); CORRADE_COMPARE(meshIndexTypeSize(MeshIndexType::UnsignedByte), 1);
CORRADE_COMPARE(meshIndexTypeSize(MeshIndexType::UnsignedShort), 2); CORRADE_COMPARE(meshIndexTypeSize(MeshIndexType::UnsignedShort), 2);
@ -209,11 +264,22 @@ void MeshTest::indexTypeSizeInvalid() {
Error redirectError{&out}; Error redirectError{&out};
meshIndexTypeSize(MeshIndexType{}); meshIndexTypeSize(MeshIndexType{});
meshIndexTypeSize(MeshIndexType(0xfe)); meshIndexTypeSize(MeshIndexType(0xbadcafe));
CORRADE_COMPARE(out.str(), CORRADE_COMPARE(out.str(),
"meshIndexTypeSize(): invalid type MeshIndexType(0x0)\n" "meshIndexTypeSize(): invalid type MeshIndexType(0x0)\n"
"meshIndexTypeSize(): invalid type MeshIndexType(0xfe)\n"); "meshIndexTypeSize(): invalid type MeshIndexType(0xbadcafe)\n");
}
void MeshTest::indexTypeSizeImplementationSpecific() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
std::ostringstream out;
Error redirectError{&out};
meshIndexTypeSize(meshIndexTypeWrap(0xdead));
CORRADE_COMPARE(out.str(), "meshIndexTypeSize(): can't determine size of an implementation-specific type 0xdead\n");
} }
void MeshTest::debugPrimitive() { void MeshTest::debugPrimitive() {
@ -235,6 +301,13 @@ void MeshTest::debugIndexType() {
CORRADE_COMPARE(o.str(), "MeshIndexType::UnsignedShort MeshIndexType(0xfe)\n"); CORRADE_COMPARE(o.str(), "MeshIndexType::UnsignedShort MeshIndexType(0xfe)\n");
} }
void MeshTest::debugIndexTypeImplementationSpecific() {
std::ostringstream out;
Debug{&out} << meshIndexTypeWrap(0xdead);
CORRADE_COMPARE(out.str(), "MeshIndexType::ImplementationSpecific(0xdead)\n");
}
void MeshTest::configurationPrimitive() { void MeshTest::configurationPrimitive() {
Utility::Configuration c; Utility::Configuration c;

1
src/Magnum/Trade/MeshData.h

@ -1932,7 +1932,6 @@ class MAGNUM_TRADE_EXPORT MeshData {
UnsignedInt _indexCount, _vertexCount; UnsignedInt _indexCount, _vertexCount;
MeshPrimitive _primitive; MeshPrimitive _primitive;
MeshIndexType _indexType; MeshIndexType _indexType;
/* 3 byte padding, reserved for 4-byte MeshIndexType */
Short _indexStride; Short _indexStride;
DataFlags _indexDataFlags, _vertexDataFlags; DataFlags _indexDataFlags, _vertexDataFlags;
/* 4 byte padding on 64bit */ /* 4 byte padding on 64bit */

3
src/Magnum/Vk/Mesh.cpp

@ -48,6 +48,9 @@ constexpr MeshIndexType IndexTypeMapping[]{
} }
MeshIndexType meshIndexType(const Magnum::MeshIndexType type) { MeshIndexType meshIndexType(const Magnum::MeshIndexType type) {
if(isMeshIndexTypeImplementationSpecific(type))
return meshIndexTypeUnwrap<MeshIndexType>(type);
CORRADE_ASSERT(UnsignedInt(type) - 1 < Containers::arraySize(IndexTypeMapping), CORRADE_ASSERT(UnsignedInt(type) - 1 < Containers::arraySize(IndexTypeMapping),
"Vk::meshIndexType(): invalid type" << type, {}); "Vk::meshIndexType(): invalid type" << type, {});
return IndexTypeMapping[UnsignedInt(type) - 1]; return IndexTypeMapping[UnsignedInt(type) - 1];

26
src/Magnum/Vk/Mesh.h

@ -81,6 +81,12 @@ MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, MeshIndexType value);
@brief Convert a generic index type to Vulkan index type @brief Convert a generic index type to Vulkan index type
@m_since_latest @m_since_latest
In case @ref isMeshIndexTypeImplementationSpecific() returns @cpp false @ce for
@p type, maps it to a corresponding Vulkan type. In case
@ref isMeshIndexTypeImplementationSpecific() returns @cpp true @ce, assumes
@p type stores a Vulkan-specific format and returns @ref meshIndexTypeUnwrap()
cast to @ref MeshIndexType.
@see @ref meshPrimitive(), @ref vertexFormat() @see @ref meshPrimitive(), @ref vertexFormat()
*/ */
MAGNUM_VK_EXPORT MeshIndexType meshIndexType(Magnum::MeshIndexType type); MAGNUM_VK_EXPORT MeshIndexType meshIndexType(Magnum::MeshIndexType type);
@ -310,7 +316,15 @@ class MAGNUM_VK_EXPORT Mesh {
* @see @ref setCount(), @ref setIndexOffset() * @see @ref setCount(), @ref setIndexOffset()
*/ */
Mesh& setIndexBuffer(VkBuffer buffer, UnsignedLong offset, MeshIndexType indexType); Mesh& setIndexBuffer(VkBuffer buffer, UnsignedLong offset, MeshIndexType indexType);
/** @overload */
/** @overload
* @brief Set an index buffer with a generic index type
*
* Note that implementation-specific values are passed as-is with
* @ref meshIndexTypeUnwrap(). It's the user responsibility to ensure
* an implementation-specific actually represents a valid Vulkan index
* type.
*/
Mesh& setIndexBuffer(VkBuffer buffer, UnsignedLong offset, Magnum::MeshIndexType indexType); Mesh& setIndexBuffer(VkBuffer buffer, UnsignedLong offset, Magnum::MeshIndexType indexType);
/** /**
@ -322,7 +336,15 @@ class MAGNUM_VK_EXPORT Mesh {
* thus doesn't have to be managed separately. * thus doesn't have to be managed separately.
*/ */
Mesh& setIndexBuffer(Buffer&& buffer, UnsignedLong offset, MeshIndexType indexType); Mesh& setIndexBuffer(Buffer&& buffer, UnsignedLong offset, MeshIndexType indexType);
/** @overload */
/** @overload
* @brief Set an index buffer with a generic index type and take over its ownership
*
* Note that implementation-specific values are passed as-is with
* @ref meshIndexTypeUnwrap(). It's the user responsibility to ensure
* an implementation-specific actually represents a valid Vulkan index
* type.
*/
Mesh& setIndexBuffer(Buffer&& buffer, UnsignedLong offset, Magnum::MeshIndexType indexType); Mesh& setIndexBuffer(Buffer&& buffer, UnsignedLong offset, Magnum::MeshIndexType indexType);
/** @brief Layout of this mesh */ /** @brief Layout of this mesh */

7
src/Magnum/Vk/Test/MeshTest.cpp

@ -39,6 +39,7 @@ struct MeshTest: TestSuite::Tester {
explicit MeshTest(); explicit MeshTest();
void mapIndexType(); void mapIndexType();
void mapIndexTypeImplementationSpecific();
void mapIndexTypeInvalid(); void mapIndexTypeInvalid();
void construct(); void construct();
@ -60,6 +61,7 @@ struct MeshTest: TestSuite::Tester {
MeshTest::MeshTest() { MeshTest::MeshTest() {
addTests({&MeshTest::mapIndexType, addTests({&MeshTest::mapIndexType,
&MeshTest::mapIndexTypeImplementationSpecific,
&MeshTest::mapIndexTypeInvalid, &MeshTest::mapIndexTypeInvalid,
&MeshTest::construct, &MeshTest::construct,
@ -95,6 +97,11 @@ void MeshTest::mapIndexType() {
CORRADE_COMPARE(meshIndexType(Magnum::MeshIndexType::UnsignedInt), MeshIndexType::UnsignedInt); CORRADE_COMPARE(meshIndexType(Magnum::MeshIndexType::UnsignedInt), MeshIndexType::UnsignedInt);
} }
void MeshTest::mapIndexTypeImplementationSpecific() {
CORRADE_COMPARE(meshIndexType(meshIndexTypeWrap(VK_INDEX_TYPE_UINT32)),
MeshIndexType::UnsignedInt);
}
void MeshTest::mapIndexTypeInvalid() { void MeshTest::mapIndexTypeInvalid() {
#ifdef CORRADE_NO_ASSERT #ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");

Loading…
Cancel
Save