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

Buffer.

Wraps a VkBuffer and its memory.

Buffer creation

Pass a BufferCreateInfo with desired usage and size to the Buffer constructor together with specifying MemoryFlags for the allocation.

#include <Magnum/Vk/BufferCreateInfo.h>



Vk::Buffer buffer{device,
    Vk::BufferCreateInfo{Vk::BufferUsage::VertexBuffer, 1024*1024},
    Vk::MemoryFlag::DeviceLocal
};

Custom memory allocation

Using Buffer(Device&, const BufferCreateInfo&, NoAllocateT), the buffer will be created without any memory bound. Buffer memory requirements can be then queried using memoryRequirements() and an allocated memory bound with bindMemory(). See Memory for further details about memory allocation.

Vk::Buffer buffer{device,
    Vk::BufferCreateInfo{Vk::BufferUsage::VertexBuffer, 1024*1024},
    NoAllocate
};

Vk::MemoryRequirements requirements = buffer.memoryRequirements();
Vk::Memory memory{device, Vk::MemoryAllocateInfo{
    requirements.size(),
    device.properties().pickMemory(Vk::MemoryFlag::DeviceLocal,
        requirements.memories())
}};

buffer.bindMemory(memory, 0);

Using bindDedicatedMemory() instead of bindMemory() will transfer ownership of the Memory to the buffer instance, making it subsequently available through dedicatedMemory(). This matches current behavior of the Buffer(Device&, const BufferCreateInfo&, MemoryFlags) constructor shown above, except that you have more control over choosing and allocating the memory.

Buffer usage

Clearing / filling buffer data

The following snippet shows zero-filling the whole buffer using CommandBuffer::fillBuffer():

Vk::Buffer buffer{device, Vk::BufferCreateInfo{
    Vk::BufferUsage::TransferDestination|, 
}, };



cmd.fillBuffer(buffer, 0x00000000);

Copying buffer data

Most common buffer copy operation is uploading vertex data from a host-visible to device-local memory. This is the preferred workflow for static data over using a host-visible memory directly, since it usually isn't the fastest for device access.

The copy is done using CommandBuffer::copyBuffer(). In most cases you'll want to combine it with a pipelineBarrier() after to make the memory visible for subsequent operations. The following snippet shows populating a device-local vertex buffer from host-visible memory:

Vk::Buffer input{device, Vk::BufferCreateInfo{
    Vk::BufferUsage::TransferSource, size
}, Vk::MemoryFlag::HostVisible};
Vk::Buffer vertices{device, Vk::BufferCreateInfo{
    Vk::BufferUsage::TransferDestination|Vk::BufferUsage::VertexBuffer, size
}, Vk::MemoryFlag::DeviceLocal};



cmd.copyBuffer({input, vertices, {
        {0, 0, size} /* Copy the whole buffer */
    }})
   .pipelineBarrier(Vk::PipelineStage::Transfer, Vk::PipelineStage::VertexInput, {
        /* Make the buffer memory available for vertex input */
        {Vk::Access::TransferWrite, Vk::Access::VertexAttributeRead, vertices}
    });

It's also possible to copy data between buffers and images, see Copying image data for examples.

Public static functions

static auto wrap(Device& device, VkBuffer handle, HandleFlags flags = {}) -> Buffer
Wrap existing Vulkan handle.

Constructors, destructors, conversion operators

Buffer(Device& device, const BufferCreateInfo& info, NoAllocateT) explicit
Construct a buffer without allocating.
Buffer(Device& device, const BufferCreateInfo& info, MemoryFlags memoryFlags) explicit
Construct a buffer.
Buffer(NoCreateT) explicit
Construct without creating the buffer.
Buffer(const Buffer&) deleted
Copying is not allowed.
Buffer(Buffer&& other) noexcept
Move constructor.
~Buffer()
Destructor.
operator VkBuffer()

Public functions

auto operator=(const Buffer&) -> Buffer& deleted
Copying is not allowed.
auto operator=(Buffer&& other) -> Buffer& noexcept
Move assignment.
auto handle() -> VkBuffer
Underlying VkBuffer handle.
auto handleFlags() const -> HandleFlags
Handle flags.
auto memoryRequirements() const -> MemoryRequirements
Buffer memory requirements.
void bindMemory(Memory& memory, UnsignedLong offset)
Bind buffer memory.
void bindDedicatedMemory(Memory&& memory)
Bind a dedicated buffer memory.
auto hasDedicatedMemory() const -> bool
Whether the buffer has a dedicated memory.
auto dedicatedMemory() -> Memory&
Dedicated buffer memory.
auto release() -> VkBuffer
Release the underlying Vulkan buffer.

Function documentation

static Buffer Magnum::Vk::Buffer::wrap(Device& device, VkBuffer handle, HandleFlags flags = {})

Wrap existing Vulkan handle.

Parameters
device Vulkan device the buffer is created on
handle The VkBuffer handle
flags Handle flags

The handle is expected to be originating from device. Unlike a buffer created using a constructor, the Vulkan buffer is by default not deleted on destruction, use flags for different behavior.

Magnum::Vk::Buffer::Buffer(Device& device, const BufferCreateInfo& info, NoAllocateT) explicit

Construct a buffer without allocating.

Parameters
device Vulkan device to create the buffer on
info Buffer creation info

Magnum::Vk::Buffer::Buffer(Device& device, const BufferCreateInfo& info, MemoryFlags memoryFlags) explicit

Construct a buffer.

Parameters
device Vulkan device to create the buffer on
info Buffer creation info
memoryFlags Memory allocation flags

Compared to Buffer(Device&, const BufferCreateInfo&, NoAllocateT) allocates a memory satisfying memoryFlags as well.

Magnum::Vk::Buffer::Buffer(NoCreateT) explicit

Construct without creating the buffer.

The constructed instance is equivalent to moved-from state. Useful in cases where you will overwrite the instance later anyway. Move another object over it to make it useful.

Magnum::Vk::Buffer::~Buffer()

Destructor.

Destroys associated VkBuffer handle, unless the instance was created using wrap() without HandleFlag::DestroyOnDestruction specified.

Magnum::Vk::Buffer::operator VkBuffer()

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

void Magnum::Vk::Buffer::bindMemory(Memory& memory, UnsignedLong offset)

Bind buffer memory.

Assumes that memory type, the amount of memory at offset and offset alignment corresponds to buffer memory requirements.

void Magnum::Vk::Buffer::bindDedicatedMemory(Memory&& memory)

Bind a dedicated buffer memory.

Equivalent to bindMemory() with offset set to 0, with the additional effect that memory ownership transfers to the buffer and is then available through dedicatedMemory().

bool Magnum::Vk::Buffer::hasDedicatedMemory() const

Whether the buffer has a dedicated memory.

Returns true if the buffer memory was bound using bindDedicatedMemory(), false otherwise.

Memory& Magnum::Vk::Buffer::dedicatedMemory()

Dedicated buffer memory.

Expects that the buffer has a dedicated memory.

VkBuffer Magnum::Vk::Buffer::release()

Release the underlying Vulkan buffer.

Releases ownership of the Vulkan buffer and returns its handle so vkDestroyBuffer() is not called on destruction. The internal state is then equivalent to moved-from state.