diff --git a/docs/gfx/Linear_allocator_1_algo_default.png b/docs/gfx/Linear_allocator_1_algo_default.png new file mode 100644 index 0000000..e3e8f47 Binary files /dev/null and b/docs/gfx/Linear_allocator_1_algo_default.png differ diff --git a/docs/gfx/Linear_allocator_2_algo_linear.png b/docs/gfx/Linear_allocator_2_algo_linear.png new file mode 100644 index 0000000..c2a38b2 Binary files /dev/null and b/docs/gfx/Linear_allocator_2_algo_linear.png differ diff --git a/docs/gfx/Linear_allocator_3_free_at_once.png b/docs/gfx/Linear_allocator_3_free_at_once.png new file mode 100644 index 0000000..a000ad5 Binary files /dev/null and b/docs/gfx/Linear_allocator_3_free_at_once.png differ diff --git a/docs/gfx/Linear_allocator_4_stack.png b/docs/gfx/Linear_allocator_4_stack.png new file mode 100644 index 0000000..4dba064 Binary files /dev/null and b/docs/gfx/Linear_allocator_4_stack.png differ diff --git a/docs/gfx/Linear_allocator_5_ring_buffer.png b/docs/gfx/Linear_allocator_5_ring_buffer.png new file mode 100644 index 0000000..0686702 Binary files /dev/null and b/docs/gfx/Linear_allocator_5_ring_buffer.png differ diff --git a/docs/gfx/Linear_allocator_6_ring_buffer_lost.png b/docs/gfx/Linear_allocator_6_ring_buffer_lost.png new file mode 100644 index 0000000..9a2338c Binary files /dev/null and b/docs/gfx/Linear_allocator_6_ring_buffer_lost.png differ diff --git a/docs/gfx/Linear_allocator_7_double_stack.png b/docs/gfx/Linear_allocator_7_double_stack.png new file mode 100644 index 0000000..77d1468 Binary files /dev/null and b/docs/gfx/Linear_allocator_7_double_stack.png differ diff --git a/docs/html/custom_memory_pools.html b/docs/html/custom_memory_pools.html index fed21c8..9f72b3f 100644 --- a/docs/html/custom_memory_pools.html +++ b/docs/html/custom_memory_pools.html @@ -78,7 +78,7 @@ $(function() {
  1. Fill VmaPoolCreateInfo structure.
  2. Call vmaCreatePool() to obtain VmaPool handle.
  3. -
  4. When making an allocation, set VmaAllocationCreateInfo::pool to this handle. You don't need to specify any other parameters of this structure, like usage.
  5. +
  6. When making an allocation, set VmaAllocationCreateInfo::pool to this handle. You don't need to specify any other parameters of this structure, like usage.

Example:

// Create a pool that can have at most 2 blocks, 128 MiB each.
VmaPoolCreateInfo poolCreateInfo = {};
poolCreateInfo.memoryTypeIndex = ...
poolCreateInfo.blockSize = 128ull * 1024 * 1024;
poolCreateInfo.maxBlockCount = 2;
VmaPool pool;
vmaCreatePool(allocator, &poolCreateInfo, &pool);
// Allocate a buffer out of it.
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufCreateInfo.size = 1024;
bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.pool = pool;
VkBuffer buf;
VmaAllocation alloc;
VmaAllocationInfo allocInfo;
vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);

You have to free all allocations made from this pool before destroying it.

@@ -88,9 +88,55 @@ Choosing memory type index
VkBufferCreateInfo exampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
exampleBufCreateInfo.size = 1024; // Whatever.
exampleBufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; // Change if needed.
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; // Change if needed.
uint32_t memTypeIndex;
vmaFindMemoryTypeIndexForBufferInfo(allocator, &exampleBufCreateInfo, &allocCreateInfo, &memTypeIndex);
VmaPoolCreateInfo poolCreateInfo = {};
poolCreateInfo.memoryTypeIndex = memTypeIndex;
// ...

When creating buffers/images allocated in that pool, provide following parameters:

- +

+Linear allocation algorithm

+

Each Vulkan memory block managed by this library has accompanying metadata that keeps track of used and unused regions. By default, the metadata structure and algorithm tries to find best place for new allocations among free regions to optimize memory usage. This way you can allocate and free objects in any order.

+
+Default allocation algorithm +
+

Sometimes there is a need to use simpler, linear allocation algorithm. You can create custom pool that uses such algorithm by adding flag VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT to VmaPoolCreateInfo::flags while creating VmaPool object. Then an alternative metadata management is used. It always creates new allocations after last one and doesn't reuse free regions after allocations freed in the middle. It results in better allocation performance and less memory consumed by metadata.

+
+Linear allocation algorithm +
+

With this one flag, you can create a custom pool that can be used in many ways: free-at-once, stack, double stack, and ring buffer. See below for details.

+

Pools with linear algorithm must have only one memory block - VmaPoolCreateInfo::maxBlockCount must be 1.

+

+Free-at-once

+

In a pool that uses linear algorithm, you still need to free all the allocations individually, e.g. by using vmaFreeMemory() or vmaDestroyBuffer(). You can free them in any order. New allocations are always made after last one - free space in the middle is not reused. However, when you release all the allocation and the pool becomes empty, allocation starts from the beginning again. This way you can use linear algorithm to speed up creation of allocations that you are going to release all at once.

+
+Free-at-once +
+

+Stack

+

When you free an allocation that was created last, its space can be reused. Thanks to this, if you always release allocations in the order opposite to their creation (LIFO - Last In First Out), you can achieve behavior of a stack.

+
+Stack +
+

+Double stack

+

The space reserved by a custom pool with linear algorithm may be used by two stacks:

+ +

To make allocation from upper stack, add flag VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT to VmaAllocationCreateInfo::flags.

+

When the two stacks' ends meet so there is not enough space between them for a new allocation, such allocation fails with usual VK_ERROR_OUT_OF_DEVICE_MEMORY error.

+
+Double stack +
+

+Ring buffer

+

When you free some allocations from the beginning and there is not enough free space for a new one at the end of a pool, allocator's "cursor" wraps around to the beginning and starts allocation there. Thanks to this, if you always release allocations in the same order as you created them (FIFO - First In First Out), you can achieve behavior of a ring buffer / queue.

+
+Ring buffer +
+

Pools with linear algorithm support lost allocations when used as ring buffer. If there is not enough free space for a new allocation, but existing allocations from the front of the queue can become lost, they become lost and the allocation succeeds.

+
+Ring buffer with lost allocations +
+