Magnum::Vk::MeshLayout class new in Git master

Mesh layout.

Wraps a

describing how vertex attributes are organized in buffers and what's the layout of each attribute. Used as an input for creating a rasterization pipeline.

Mesh layout setup

As an example let's assume a shader expects positions, texture coordinates and normals in locations 0, 1 and 5, respectively. If we'd have them stored interleaved in a single buffer, the layout description could look like this:

constexpr UnsignedInt Binding = 0;

constexpr UnsignedInt PositionLocation = 0;
constexpr UnsignedInt TextureLocation = 1;
constexpr UnsignedInt NormalLocation = 5;

Vk::MeshLayout meshLayout{MeshPrimitive::Triangles};
meshLayout
    .addBinding(Binding, 8*sizeof(Float))
    .addAttribute(PositionLocation, Binding, VertexFormat::Vector3, 0)
    .addAttribute(TextureLocation, Binding, VertexFormat::Vector2, 3*sizeof(Float))
    .addAttribute(NormalLocation, Binding, VertexFormat::Vector3, 5*sizeof(Float));

The Binding is then subsequently used as a binding index for a concrete vertex buffer when drawing, which is described in the Mesh class documentation.

Layout comparison

Because a Pipeline is tied to a particular mesh layout (apart from certain aspects that can be controlled via dynamic state), new pipelines should be created only when the layout is actually different. For that, the class provides a operator==(), which returns true when the two layouts match.

Constructors, destructors, conversion operators

MeshLayout(MeshPrimitive primitive) explicit
Constructor.
MeshLayout(Magnum::MeshPrimitive primitive) explicit
Construct with a generic primitive type.
MeshLayout(NoInitT) explicit noexcept
Construct without initializing the contents.
MeshLayout(const VkPipelineVertexInputStateCreateInfo& vertexInfo, const VkPipelineInputAssemblyStateCreateInfo& assemblyInfo) explicit
Construct from existing data.
MeshLayout(const MeshLayout&) deleted
Copying is not allowed.
MeshLayout(MeshLayout&& other) noexcept
Move constructor.
operator const VkPipelineVertexInputStateCreateInfo*() const
operator const VkPipelineInputAssemblyStateCreateInfo*() const

Public functions

auto operator=(const MeshLayout&) -> MeshLayout& deleted
Copying is not allowed.
auto operator=(MeshLayout&& other) -> MeshLayout& noexcept
Move assignment.
auto operator==(const MeshLayout& other) const -> bool
Equality comparison.
auto operator!=(const MeshLayout& other) const -> bool
Non-equality comparison.
auto addBinding(UnsignedInt binding, UnsignedInt stride) & -> MeshLayout&
Add a buffer binding.
auto addBinding(UnsignedInt binding, UnsignedInt stride) && -> MeshLayout&&
auto addInstancedBinding(UnsignedInt binding, UnsignedInt stride, UnsignedInt divisor = 1) & -> MeshLayout&
Add an instanced buffer binding.
auto addInstancedBinding(UnsignedInt binding, UnsignedInt stride, UnsignedInt divisor = 1) && -> MeshLayout&&
auto addAttribute(UnsignedInt location, UnsignedInt binding, VertexFormat format, UnsignedInt offset) & -> MeshLayout&
Add an attribute.
auto addAttribute(UnsignedInt location, UnsignedInt binding, VertexFormat format, UnsignedInt offset) && -> MeshLayout&&
auto addAttribute(UnsignedInt location, UnsignedInt binding, Magnum::VertexFormat format, UnsignedInt offset) & -> MeshLayout&
Add an attribute with a generic primitive type.
auto addAttribute(UnsignedInt location, UnsignedInt binding, Magnum::VertexFormat format, UnsignedInt offset) && -> MeshLayout&&
auto vkPipelineVertexInputStateCreateInfo() -> VkPipelineVertexInputStateCreateInfo&
Underlying VkPipelineVertexInputStateCreateInfo structure.
auto vkPipelineVertexInputStateCreateInfo() const -> const VkPipelineVertexInputStateCreateInfo&
auto vkPipelineInputAssemblyStateCreateInfo() -> VkPipelineInputAssemblyStateCreateInfo&
Underlying VkPipelineInputAssemblyStateCreateInfo structure.
auto vkPipelineInputAssemblyStateCreateInfo() const -> const VkPipelineInputAssemblyStateCreateInfo&

Function documentation

Magnum::Vk::MeshLayout::MeshLayout(MeshPrimitive primitive) explicit

Constructor.

Parameters
primitive Mesh primitive

The following VkPipelineVertexInputStateCreateInfo fields are pre-filled in addition to sType, everything else is zero-filled:

  • (none)

The following VkPipelineInputAssemblyStateCreateInfo fields are pre-filled in addition to sType, everything else is zero-filled:

  • topology to primitive

Magnum::Vk::MeshLayout::MeshLayout(Magnum::MeshPrimitive primitive) explicit

Construct with a generic primitive type.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Note that implementation-specific values are passed as-is with meshPrimitiveUnwrap(). It's the user responsibility to ensure an implementation-specific value actually represents a valid Vulkan primitive type.

Magnum::Vk::MeshLayout::MeshLayout(NoInitT) explicit noexcept

Construct without initializing the contents.

Note that not even the sType fields are set — the structures have to be fully initialized afterwards in order to be usable.

Magnum::Vk::MeshLayout::MeshLayout(const VkPipelineVertexInputStateCreateInfo& vertexInfo, const VkPipelineInputAssemblyStateCreateInfo& assemblyInfo) explicit

Construct from existing data.

Copies the existing values verbatim, pointers are kept unchanged without taking over the ownership. Modifying the newly created instance will not modify the original data nor the pointed-to data.

Magnum::Vk::MeshLayout::operator const VkPipelineVertexInputStateCreateInfo*() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Magnum::Vk::MeshLayout::operator const VkPipelineInputAssemblyStateCreateInfo*() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

bool Magnum::Vk::MeshLayout::operator==(const MeshLayout& other) const

Equality comparison.

Expects that neither instance has external pNext or other data pointers, as otherwise the implementation would have to be too complex and slow — in short that means all bindings and attributes should be added via addBinding(), addInstancedBinding() and addAttribute(), not by conversion from raw Vulkan structures or by direct editing of the underlying data.

Given that addBinding(), addInstancedBinding() and addAttribute() enforce monotonically increasing order, comparison is simple with a $ \mathcal{O}(n) $ complexity in the total number of bindings and attachments.

bool Magnum::Vk::MeshLayout::operator!=(const MeshLayout& other) const

Non-equality comparison.

Inverse of operator==(), see its documentation for more information.

MeshLayout& Magnum::Vk::MeshLayout::addBinding(UnsignedInt binding, UnsignedInt stride) &

Add a buffer binding.

Parameters
binding Binding index, to which a buffer subrange will be bound when drawing the mesh. Has to be unique among all addBinding() and addInstancedBinding() calls, and monotonically increasing in order to make the layouts efficiently comparable.
stride Binding stride, in bytes
Returns Reference to self (for method chaining)

Adds a new VkVertexInputBindingDescription structure to vkPipelineVertexInputStateCreateInfo() with the following fields set:

MeshLayout&& Magnum::Vk::MeshLayout::addBinding(UnsignedInt binding, UnsignedInt stride) &&

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

MeshLayout& Magnum::Vk::MeshLayout::addInstancedBinding(UnsignedInt binding, UnsignedInt stride, UnsignedInt divisor = 1) &

Add an instanced buffer binding.

Parameters
binding Binding index, to which a buffer subrange will be bound when drawing the mesh. Has to be unique among all addBinding() and addInstancedBinding() calls, and monotonically increasing in order to make the layouts efficiently comparable.
stride Binding stride, in bytes
divisor Attribute divisor. 1 means the attribute will be advanced for each instance, larger values will mean n instances will be drawn using the same attribute, 0 will make all instances use a single attribute (which is effectively the same as setting divisor to instance count).
Returns Reference to self (for method chaining)

Compared to addBinding(), sets inputRate to VK_VERTEX_INPUT_RATE_INSTANCE. If divisor is not 1, a new VkVertexInputBindingDivisorDescriptionEXT structure is added to VkPipelineVertexInputDivisorStateCreateInfoEXT which is then referenced from the pNext chain of vkPipelineVertexInputStateCreateInfo(), with the following fields set:

  • binding
  • divisor

MeshLayout&& Magnum::Vk::MeshLayout::addInstancedBinding(UnsignedInt binding, UnsignedInt stride, UnsignedInt divisor = 1) &&

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

MeshLayout& Magnum::Vk::MeshLayout::addAttribute(UnsignedInt location, UnsignedInt binding, VertexFormat format, UnsignedInt offset) &

Add an attribute.

Parameters
location Attribute location, matching a shader input. Has to be monotonically increasing in order to make the layouts efficiently comparable.
binding Binding index, corresponding to the binding parameter of one of the addBinding() / addInstancedBinding() calls.
format Vertex format
offset Attribute offset in bytes inside stride of given binding
Returns Reference to self (for method chaining)

Adds a new VkVertexInputAttributeDescription structure to vkPipelineVertexInputStateCreateInfo() with the following fields set:

  • location
  • binding
  • format
  • offset

MeshLayout&& Magnum::Vk::MeshLayout::addAttribute(UnsignedInt location, UnsignedInt binding, VertexFormat format, UnsignedInt offset) &&

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

MeshLayout& Magnum::Vk::MeshLayout::addAttribute(UnsignedInt location, UnsignedInt binding, Magnum::VertexFormat format, UnsignedInt offset) &

Add an attribute with a generic primitive type.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Note that implementation-specific values are passed as-is with vertexFormatUnwrap(). It's the user responsibility to ensure an implementation-specific value actually represents a valid Vulkan vertex format.

MeshLayout&& Magnum::Vk::MeshLayout::addAttribute(UnsignedInt location, UnsignedInt binding, Magnum::VertexFormat format, UnsignedInt offset) &&

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

const VkPipelineVertexInputStateCreateInfo& Magnum::Vk::MeshLayout::vkPipelineVertexInputStateCreateInfo() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

VkPipelineInputAssemblyStateCreateInfo& Magnum::Vk::MeshLayout::vkPipelineInputAssemblyStateCreateInfo()

Underlying VkPipelineInputAssemblyStateCreateInfo structure.

If addInstancedBinding() was called with divisor different than 0, the pNext chain contains the VkPipelineVertexInputDivisorStateCreateInfoEXT structure.

const VkPipelineInputAssemblyStateCreateInfo& Magnum::Vk::MeshLayout::vkPipelineInputAssemblyStateCreateInfo() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.