<divclass="textblock"><p>A memory pool contains a number of <code>VkDeviceMemory</code> blocks. The library automatically creates and manages default pool for each memory type available on the device. Default memory pool automatically grows in size. Size of allocated blocks is also variable and managed automatically. You are using default pools whenever you leave <aclass="el"href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150"title="Pool that this allocation should be created in.">VmaAllocationCreateInfo::pool</a> = null.</p>
<li>Use extra parameters for a set of your allocations that are available in <aclass="el"href="struct_vma_pool_create_info.html"title="Describes parameter of created VmaPool.">VmaPoolCreateInfo</a> but not in <aclass="el"href="struct_vma_allocation_create_info.html"title="Parameters of new VmaAllocation.">VmaAllocationCreateInfo</a> - e.g., custom minimum alignment, custom <code>pNext</code> chain.</li>
<li>When making an allocation, set <aclass="el"href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150"title="Pool that this allocation should be created in.">VmaAllocationCreateInfo::pool</a> to this handle. You don't need to specify any other parameters of this structure, like <code>usage</code>.</li>
<divclass="line">VkResult res = <aclass="code hl_function"href="group__group__alloc.html#gae790ab9ffaf7667fb8f62523e6897888">vmaFindMemoryTypeIndexForBufferInfo</a>(allocator,</div>
<divclass="ttc"id="astruct_vma_allocation_create_info_html"><divclass="ttname"><ahref="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a></div><divclass="ttdoc">Parameters of new VmaAllocation.</div><divclass="ttdef"><b>Definition</b> vk_mem_alloc.h:1263</div></div>
<divclass="ttc"id="astruct_vma_allocation_create_info_html_a6272c0555cfd1fe28bff1afeb6190150"><divclass="ttname"><ahref="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">VmaAllocationCreateInfo::pool</a></div><divclass="ttdeci">VmaPool pool</div><divclass="ttdoc">Pool that this allocation should be created in.</div><divclass="ttdef"><b>Definition</b> vk_mem_alloc.h:1295</div></div>
<divclass="ttc"id="astruct_vma_allocation_create_info_html_accb8b06b1f677d858cb9af20705fa910"><divclass="ttname"><ahref="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">VmaAllocationCreateInfo::usage</a></div><divclass="ttdeci">VmaMemoryUsage usage</div><divclass="ttdoc">Intended usage of memory.</div><divclass="ttdef"><b>Definition</b> vk_mem_alloc.h:1271</div></div>
<divclass="ttc"id="astruct_vma_allocation_html"><divclass="ttname"><ahref="struct_vma_allocation.html">VmaAllocation</a></div><divclass="ttdoc">Represents single memory allocation.</div></div>
<divclass="ttc"id="astruct_vma_pool_create_info_html"><divclass="ttname"><ahref="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a></div><divclass="ttdoc">Describes parameter of created VmaPool.</div><divclass="ttdef"><b>Definition</b> vk_mem_alloc.h:1314</div></div>
<divclass="ttc"id="astruct_vma_pool_create_info_html_a596fa76b685d3f1f688f84a709a5b319"><divclass="ttname"><ahref="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">VmaPoolCreateInfo::memoryTypeIndex</a></div><divclass="ttdeci">uint32_t memoryTypeIndex</div><divclass="ttdoc">Vulkan memory type index to allocate this pool from.</div><divclass="ttdef"><b>Definition</b> vk_mem_alloc.h:1317</div></div>
<divclass="ttc"id="astruct_vma_pool_create_info_html_aa4265160536cdb9be821b7686c16c676"><divclass="ttname"><ahref="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676">VmaPoolCreateInfo::blockSize</a></div><divclass="ttdeci">VkDeviceSize blockSize</div><divclass="ttdoc">Size of a single VkDeviceMemory block to be allocated as part of this pool, in bytes....</div><divclass="ttdef"><b>Definition</b> vk_mem_alloc.h:1330</div></div>
<divclass="ttc"id="astruct_vma_pool_create_info_html_ae41142f2834fcdc82baa4883c187b75c"><divclass="ttname"><ahref="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">VmaPoolCreateInfo::maxBlockCount</a></div><divclass="ttdeci">size_t maxBlockCount</div><divclass="ttdoc">Maximum number of blocks that can be allocated in this pool. Optional.</div><divclass="ttdef"><b>Definition</b> vk_mem_alloc.h:1343</div></div>
</div><!-- fragment --><p>New versions of this library support creating dedicated allocations in custom pools. It is supported only when <aclass="el"href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676"title="Size of a single VkDeviceMemory block to be allocated as part of this pool, in bytes....">VmaPoolCreateInfo::blockSize</a> = 0. To use this feature, set <aclass="el"href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150"title="Pool that this allocation should be created in.">VmaAllocationCreateInfo::pool</a> to the pointer to your custom pool and <aclass="el"href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b"title="Use VmaAllocationCreateFlagBits enum.">VmaAllocationCreateInfo::flags</a> to <aclass="el"href="group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f"title="Set this flag if the allocation should have its own memory block.">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a>.</p>
<p>When creating a pool, you must explicitly specify memory type index. To find the one suitable for your buffers or images, you can use helper functions <aclass="el"href="group__group__alloc.html#gae790ab9ffaf7667fb8f62523e6897888"title="Helps to find memoryTypeIndex, given VkBufferCreateInfo and VmaAllocationCreateInfo.">vmaFindMemoryTypeIndexForBufferInfo()</a>, <aclass="el"href="group__group__alloc.html#ga088da83d8eaf3ce9056d9ea0b981d472"title="Helps to find memoryTypeIndex, given VkImageCreateInfo and VmaAllocationCreateInfo.">vmaFindMemoryTypeIndexForImageInfo()</a>. You need to provide structures with example parameters of buffers or images that you are going to create in that pool.</p>
<li><code>VkBufferCreateInfo</code>: Prefer to pass same parameters as above. Otherwise you risk creating resources in a memory type that is not suitable for them, which may result in undefined behavior. Using different <code>VK_BUFFER_USAGE_</code> flags may work, but you shouldn't create images in a pool intended for buffers or the other way around.</li>
<li><aclass="el"href="struct_vma_allocation_create_info.html"title="Parameters of new VmaAllocation.">VmaAllocationCreateInfo</a>: You don't need to pass same parameters. Fill only <code>pool</code> member. Other members are ignored anyway.</li>
<p>Custom pools are commonly overused by VMA users. While it may feel natural to keep some logical groups of resources separate in memory, in most cases it does more harm than good. Using custom pool shouldn't be your first choice. Instead, please make all allocations from default pools first and only use custom pools if you can prove and measure that it is beneficial in some way, e.g. it results in lower memory usage, better performance, etc.</p>
<p>Using custom pools has disadvantages:</p>
<ul>
<li>Each pool has its own collection of <code>VkDeviceMemory</code> blocks. Some of them may be partially or even completely empty. Spreading allocations across multiple pools increases the amount of wasted (allocated but unbound) memory.</li>
<li>You must manually choose specific memory type to be used by a custom pool (set as <aclass="el"href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319"title="Vulkan memory type index to allocate this pool from.">VmaPoolCreateInfo::memoryTypeIndex</a>). When using default pools, best memory type for each of your allocations can be selected automatically using a carefully design algorithm that works across all kinds of GPUs.</li>
<li>If an allocation from a custom pool at specific memory type fails, entire allocation operation returns failure. When using default pools, VMA tries another compatible memory type.</li>
<li>If you set <aclass="el"href="struct_vma_pool_create_info.html#aa4265160536cdb9be821b7686c16c676"title="Size of a single VkDeviceMemory block to be allocated as part of this pool, in bytes....">VmaPoolCreateInfo::blockSize</a> != 0, each memory block has the same size, while default pools start from small blocks and only allocate next blocks larger and larger up to the preferred block size.</li>
</ul>
<p>Many of the common concerns can be addressed in a different way than using custom pools:</p>
<li>If you want to keep your allocations of certain size (small versus large) or certain lifetime (transient versus long lived) separate, you likely don't need to. VMA uses a high quality allocation algorithm that manages memory well in various cases. Please measure and check if using custom pools provides a benefit.</li>
<li>If you want to keep your images and buffers separate, you don't need to. VMA respects <code>bufferImageGranularity</code> limit automatically.</li>
<li>If you want to keep your mapped and not mapped allocations separate, you don't need to. VMA respects <code>nonCoherentAtomSize</code> limit automatically. It also maps only those <code>VkDeviceMemory</code> blocks that need to map any allocation. It even tries to keep mappable and non-mappable allocations in separate blocks to minimize the amount of mapped memory.</li>
<li>If you want to choose a custom size for the default memory block, you can set it globally instead using <aclass="el"href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a"title="Preferred size of a single VkDeviceMemory block to be allocated from large heaps > 1 GiB....">VmaAllocatorCreateInfo::preferredLargeHeapBlockSize</a>.</li>
<li>If you want to select specific memory type for your allocation, you can set <aclass="el"href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055"title="Bitmask containing one bit set for every memory type acceptable for this allocation.">VmaAllocationCreateInfo::memoryTypeBits</a> to <code>(1u << myMemoryTypeIndex)</code> instead.</li>
<li>If you need to create a buffer with certain minimum alignment, you can still do it using default pools with dedicated function <aclass="el"href="group__group__alloc.html#gaa06a690013a0d01e60894ac378083834"title="Creates a buffer with additional minimum alignment.">vmaCreateBufferWithAlignment()</a>.</li>
<p>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.</p>
<p>Sometimes there is a need to use simpler, linear allocation algorithm. You can create custom pool that uses such algorithm by adding flag <aclass="el"href="group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726"title="Enables alternative, linear allocation algorithm in this pool.">VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT</a> to <aclass="el"href="struct_vma_pool_create_info.html#a8405139f63d078340ae74513a59f5446"title="Use combination of VmaPoolCreateFlagBits.">VmaPoolCreateInfo::flags</a> while creating <aclass="el"href="struct_vma_pool.html"title="Represents custom memory pool.">VmaPool</a> 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.</p>
<p>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. You don't need to specify explicitly which of these options you are going to use - it is detected automatically.</p>
<p>In a pool that uses linear algorithm, you still need to free all the allocations individually, e.g. by using <aclass="el"href="group__group__alloc.html#ga5fea5518972ae9094b1526cbcb19b05f"title="Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(),...">vmaFreeMemory()</a> or <aclass="el"href="group__group__alloc.html#ga0d9f4e4ba5bf9aab1f1c746387753d77"title="Destroys Vulkan buffer and frees allocated memory.">vmaDestroyBuffer()</a>. 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.</p>
<p>This mode is also available for pools created with <aclass="el"href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c"title="Maximum number of blocks that can be allocated in this pool. Optional.">VmaPoolCreateInfo::maxBlockCount</a> value that allows multiple memory blocks.</p>
<p>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.</p>
<p>This mode is also available for pools created with <aclass="el"href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c"title="Maximum number of blocks that can be allocated in this pool. Optional.">VmaPoolCreateInfo::maxBlockCount</a> value that allows multiple memory blocks.</p>
<p>To make allocation from the upper stack, add flag <aclass="el"href="group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df">VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT</a> to <aclass="el"href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b"title="Use VmaAllocationCreateFlagBits enum.">VmaAllocationCreateInfo::flags</a>.</p>
<p>Double stack is available only in pools with one memory block - <aclass="el"href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c"title="Maximum number of blocks that can be allocated in this pool. Optional.">VmaPoolCreateInfo::maxBlockCount</a> must be 1. Otherwise behavior is undefined.</p>
<p>When the two stacks' ends meet so there is not enough space between them for a new allocation, such allocation fails with usual <code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code> error.</p>
<p>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.</p>
<p>Ring buffer is available only in pools with one memory block - <aclass="el"href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c"title="Maximum number of blocks that can be allocated in this pool. Optional.">VmaPoolCreateInfo::maxBlockCount</a> must be 1. Otherwise behavior is undefined.</p>
<dlclass="section note"><dt>Note</dt><dd><aclass="el"href="defragmentation.html">Defragmentation</a> is not supported in custom pools created with <aclass="el"href="group__group__alloc.html#gga9a7c45f9c863695d98c83fa5ac940fe7a13c8a444197c67866be9cb05599fc726"title="Enables alternative, linear allocation algorithm in this pool.">VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT</a>. </dd></dl>