Creating a staging buffer
Creating a staging buffer is like creating a regular buffer but requires flags that specify that the buffer is host-visible. In this recipe, we will show how to create a buffer that can be used as a staging buffer – one that can be used as an intermediary destination of the data being uploaded from your application on its way to a device-local memory.
Getting ready
The Creating buffers recipe explains how to create buffers in general, while this recipe shows which flags and parameters you need to create a staging buffer.
How to do it…
VkBufferCreateInfo::usage
needs to contain VK_BUFFER_USAGE_TRANSFER_SRC_BIT
as it will be the source operation for a vkCmdCopyBuffer
command:
const VkBufferCreateInfo stagingBufferInfo = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .size = size, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, }; const VmaAllocationCreateInfo stagingAllocationCreateInfo = { .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT, .usage = VMA_MEMORY_USAGE_CPU_ONLY, }; const VmaAllocationCreateFlagBits allocCreateInfo = { VMA_ALLOCATION_CREATE_MAPPED_BIT, VMA_MEMORY_USAGE_CPU_ONLY, }; VmaAllocation allocation; // Needs to live until the // buffer is destroyed VK_CHECK(vmaCreateBuffer(allocator, &stagingBufferInfo, &allocCreateInfo, &buffer, &allocation, nullptr));
A staging buffer may be better implemented using a wrapper in your application. A wrapper can increase or decrease the size of the buffer as needed, for example. One staging buffer may be enough for your application, but you need to watch the requirements imposed by some architectures.