<divclass="textblock"><p>As an extra feature, the core allocation algorithm of the library is exposed through a simple and convenient API of "virtual allocator". It doesn't allocate any real GPU memory. It just keeps track of used and free regions of a "virtual block". You can use it to allocate your own memory or other objects, even completely unrelated to Vulkan. A common use case is sub-allocation of pieces of one large GPU buffer.</p>
<p>To use this functionality, there is no main "allocator" object. You don't need to have <aclass="el"href="struct_vma_allocator.html"title="Represents main object of this library initialized.">VmaAllocator</a> object created. All you need to do is to create a separate <aclass="el"href="struct_vma_virtual_block.html"title="Handle to a virtual block object that allows to use core allocation algorithm without allocating any ...">VmaVirtualBlock</a> object for each block of memory you want to be managed by the allocator:</p>
<oltype="1">
<li>Fill in <aclass="el"href="struct_vma_virtual_block_create_info.html"title="Parameters of created VmaVirtualBlock object to be passed to vmaCreateVirtualBlock().">VmaVirtualBlockCreateInfo</a> structure.</li>
<li>Call <aclass="el"href="group__group__virtual.html#gab585754076877265fdae33e5c40ef13b"title="Creates new VmaVirtualBlock object.">vmaCreateVirtualBlock()</a>. Get new <aclass="el"href="struct_vma_virtual_block.html"title="Handle to a virtual block object that allows to use core allocation algorithm without allocating any ...">VmaVirtualBlock</a> object.</li>
<divclass="line">VkResult res = <aclass="code hl_function"href="group__group__virtual.html#gab585754076877265fdae33e5c40ef13b">vmaCreateVirtualBlock</a>(&blockCreateInfo, &block);</div>
<divclass="ttc"id="agroup__group__virtual_html_gab585754076877265fdae33e5c40ef13b"><divclass="ttname"><ahref="group__group__virtual.html#gab585754076877265fdae33e5c40ef13b">vmaCreateVirtualBlock</a></div><divclass="ttdeci">VkResult vmaCreateVirtualBlock(const VmaVirtualBlockCreateInfo *pCreateInfo, VmaVirtualBlock *pVirtualBlock)</div><divclass="ttdoc">Creates new VmaVirtualBlock object.</div></div>
<divclass="ttc"id="astruct_vma_virtual_block_create_info_html"><divclass="ttname"><ahref="struct_vma_virtual_block_create_info.html">VmaVirtualBlockCreateInfo</a></div><divclass="ttdoc">Parameters of created VmaVirtualBlock object to be passed to vmaCreateVirtualBlock().</div><divclass="ttdef"><b>Definition:</b> vk_mem_alloc.h:1459</div></div>
<divclass="ttc"id="astruct_vma_virtual_block_create_info_html_a670ab8c6a6e822f3c36781d79e8824e9"><divclass="ttname"><ahref="struct_vma_virtual_block_create_info.html#a670ab8c6a6e822f3c36781d79e8824e9">VmaVirtualBlockCreateInfo::size</a></div><divclass="ttdeci">VkDeviceSize size</div><divclass="ttdoc">Total size of the virtual block.</div><divclass="ttdef"><b>Definition:</b> vk_mem_alloc.h:1465</div></div>
<divclass="ttc"id="astruct_vma_virtual_block_html"><divclass="ttname"><ahref="struct_vma_virtual_block.html">VmaVirtualBlock</a></div><divclass="ttdoc">Handle to a virtual block object that allows to use core allocation algorithm without allocating any ...</div></div>
</div><!-- fragment --><h1><aclass="anchor"id="virtual_allocator_making_virtual_allocations"></a>
<p><aclass="el"href="struct_vma_virtual_block.html"title="Handle to a virtual block object that allows to use core allocation algorithm without allocating any ...">VmaVirtualBlock</a> object contains internal data structure that keeps track of free and occupied regions using the same code as the main Vulkan memory allocator. Similarly to <aclass="el"href="struct_vma_allocation.html"title="Represents single memory allocation.">VmaAllocation</a> for standard GPU allocations, there is <aclass="el"href="struct_vma_virtual_allocation.html"title="Represents single memory allocation done inside VmaVirtualBlock.">VmaVirtualAllocation</a> type that represents an opaque handle to an allocation withing the virtual block.</p>
<li>Fill in <aclass="el"href="struct_vma_virtual_allocation_create_info.html"title="Parameters of created virtual allocation to be passed to vmaVirtualAllocate().">VmaVirtualAllocationCreateInfo</a> structure.</li>
<li>Call <aclass="el"href="group__group__virtual.html#ga6b7cdcc1c3e5103c323fedc4e1319e01"title="Allocates new virtual allocation inside given VmaVirtualBlock.">vmaVirtualAllocate()</a>. Get new <aclass="el"href="struct_vma_virtual_allocation.html"title="Represents single memory allocation done inside VmaVirtualBlock.">VmaVirtualAllocation</a> object that represents the allocation. You can also receive <code>VkDeviceSize offset</code> that was assigned to the allocation.</li>
<divclass="ttc"id="agroup__group__virtual_html_ga6b7cdcc1c3e5103c323fedc4e1319e01"><divclass="ttname"><ahref="group__group__virtual.html#ga6b7cdcc1c3e5103c323fedc4e1319e01">vmaVirtualAllocate</a></div><divclass="ttdeci">VkResult vmaVirtualAllocate(VmaVirtualBlock virtualBlock, const VmaVirtualAllocationCreateInfo *pCreateInfo, VmaVirtualAllocation *pAllocation, VkDeviceSize *pOffset)</div><divclass="ttdoc">Allocates new virtual allocation inside given VmaVirtualBlock.</div></div>
<divclass="ttc"id="astruct_vma_virtual_allocation_create_info_html"><divclass="ttname"><ahref="struct_vma_virtual_allocation_create_info.html">VmaVirtualAllocationCreateInfo</a></div><divclass="ttdoc">Parameters of created virtual allocation to be passed to vmaVirtualAllocate().</div><divclass="ttdef"><b>Definition:</b> vk_mem_alloc.h:1480</div></div>
<divclass="ttc"id="astruct_vma_virtual_allocation_create_info_html_aae08752b86817abd0d944c6025dc603e"><divclass="ttname"><ahref="struct_vma_virtual_allocation_create_info.html#aae08752b86817abd0d944c6025dc603e">VmaVirtualAllocationCreateInfo::size</a></div><divclass="ttdeci">VkDeviceSize size</div><divclass="ttdoc">Size of the allocation.</div><divclass="ttdef"><b>Definition:</b> vk_mem_alloc.h:1485</div></div>
<divclass="ttc"id="astruct_vma_virtual_allocation_html"><divclass="ttname"><ahref="struct_vma_virtual_allocation.html">VmaVirtualAllocation</a></div><divclass="ttdoc">Represents single memory allocation done inside VmaVirtualBlock.</div></div>
<p>When no longer needed, an allocation can be freed by calling <aclass="el"href="group__group__virtual.html#ga09fc688c0c3653ff23723b037e5d5033"title="Frees virtual allocation inside given VmaVirtualBlock.">vmaVirtualFree()</a>. You can only pass to this function an allocation that was previously returned by <aclass="el"href="group__group__virtual.html#ga6b7cdcc1c3e5103c323fedc4e1319e01"title="Allocates new virtual allocation inside given VmaVirtualBlock.">vmaVirtualAllocate()</a> called for the same <aclass="el"href="struct_vma_virtual_block.html"title="Handle to a virtual block object that allows to use core allocation algorithm without allocating any ...">VmaVirtualBlock</a>.</p>
<p>When whole block is no longer needed, the block object can be released by calling <aclass="el"href="group__group__virtual.html#ga3795f7783ae2c182cede067d656f66a5"title="Destroys VmaVirtualBlock object.">vmaDestroyVirtualBlock()</a>. All allocations must be freed before the block is destroyed, which is checked internally by an assert. However, if you don't want to call <aclass="el"href="group__group__virtual.html#ga09fc688c0c3653ff23723b037e5d5033"title="Frees virtual allocation inside given VmaVirtualBlock.">vmaVirtualFree()</a> for each allocation, you can use <aclass="el"href="group__group__virtual.html#ga5eda6f55919fb05bd2f56a112590c571"title="Frees all virtual allocations inside given VmaVirtualBlock.">vmaClearVirtualBlock()</a> to free them all at once - a feature not available in normal Vulkan memory allocator. Example:</p>
<p>You can attach a custom pointer to each allocation by using <aclass="el"href="group__group__virtual.html#ga001ea1850458a4062b829e09c303fca2"title="Changes custom pointer associated with given virtual allocation.">vmaSetVirtualAllocationUserData()</a>. Its default value is null. It can be used to store any data that needs to be associated with that allocation - e.g. an index, a handle, or a pointer to some larger data structure containing more information. Example:</p>
<divclass="ttc"id="agroup__group__virtual_html_ga001ea1850458a4062b829e09c303fca2"><divclass="ttname"><ahref="group__group__virtual.html#ga001ea1850458a4062b829e09c303fca2">vmaSetVirtualAllocationUserData</a></div><divclass="ttdeci">void vmaSetVirtualAllocationUserData(VmaVirtualBlock virtualBlock, VmaVirtualAllocation allocation, void *pUserData)</div><divclass="ttdoc">Changes custom pointer associated with given virtual allocation.</div></div>
</div><!-- fragment --><p>The pointer can later be fetched, along with allocation offset and size, by passing the allocation handle to function <aclass="el"href="group__group__virtual.html#ga8ee14ceb1fe033ec84d8aa29e1f75afa"title="Returns information about a specific virtual allocation within a virtual block, like its size and pUs...">vmaGetVirtualAllocationInfo()</a> and inspecting returned structure <aclass="el"href="struct_vma_virtual_allocation_info.html"title="Parameters of an existing virtual allocation, returned by vmaGetVirtualAllocationInfo().">VmaVirtualAllocationInfo</a>. If you allocated a new object to be used as the custom pointer, don't forget to delete that object before freeing the allocation! Example:</p>
<divclass="ttc"id="agroup__group__virtual_html_ga8ee14ceb1fe033ec84d8aa29e1f75afa"><divclass="ttname"><ahref="group__group__virtual.html#ga8ee14ceb1fe033ec84d8aa29e1f75afa">vmaGetVirtualAllocationInfo</a></div><divclass="ttdeci">void vmaGetVirtualAllocationInfo(VmaVirtualBlock virtualBlock, VmaVirtualAllocation allocation, VmaVirtualAllocationInfo *pVirtualAllocInfo)</div><divclass="ttdoc">Returns information about a specific virtual allocation within a virtual block, like its size and pUs...</div></div>
<divclass="ttc"id="astruct_vma_virtual_allocation_info_html"><divclass="ttname"><ahref="struct_vma_virtual_allocation_info.html">VmaVirtualAllocationInfo</a></div><divclass="ttdoc">Parameters of an existing virtual allocation, returned by vmaGetVirtualAllocationInfo().</div><divclass="ttdef"><b>Definition:</b> vk_mem_alloc.h:1503</div></div>
<divclass="ttc"id="astruct_vma_virtual_allocation_info_html_a41d5cb09357656411653d82fee436f45"><divclass="ttname"><ahref="struct_vma_virtual_allocation_info.html#a41d5cb09357656411653d82fee436f45">VmaVirtualAllocationInfo::pUserData</a></div><divclass="ttdeci">void * pUserData</div><divclass="ttdoc">Custom pointer associated with the allocation.</div><divclass="ttdef"><b>Definition:</b> vk_mem_alloc.h:1518</div></div>
</div><!-- fragment --><h1><aclass="anchor"id="virtual_allocator_alignment_and_units"></a>
Alignment and units</h1>
<p>It feels natural to express sizes and offsets in bytes. If an offset of an allocation needs to be aligned to a multiply of some number (e.g. 4 bytes), you can fill optional member <aclass="el"href="struct_vma_virtual_allocation_create_info.html#a9d19709872fc1904a105079e1c885821"title="Required alignment of the allocation. Optional.">VmaVirtualAllocationCreateInfo::alignment</a> to request it. Example:</p>
<divclass="line">allocCreateInfo.<aclass="code hl_variable"href="struct_vma_virtual_allocation_create_info.html#a9d19709872fc1904a105079e1c885821">alignment</a> = 4; <spanclass="comment">// Returned offset must be a multiply of 4 B</span></div>
<divclass="ttc"id="astruct_vma_virtual_allocation_create_info_html_a9d19709872fc1904a105079e1c885821"><divclass="ttname"><ahref="struct_vma_virtual_allocation_create_info.html#a9d19709872fc1904a105079e1c885821">VmaVirtualAllocationCreateInfo::alignment</a></div><divclass="ttdeci">VkDeviceSize alignment</div><divclass="ttdoc">Required alignment of the allocation. Optional.</div><divclass="ttdef"><b>Definition:</b> vk_mem_alloc.h:1490</div></div>
</div><!-- fragment --><p>Alignments of different allocations made from one block may vary. However, if all alignments and sizes are always multiply of some size e.g. 4 B or <code>sizeof(MyDataStruct)</code>, you can express all sizes, alignments, and offsets in multiples of that size instead of individual bytes. It might be more convenient, but you need to make sure to use this new unit consistently in all the places:</p>
<ul>
<li><aclass="el"href="struct_vma_virtual_block_create_info.html#a670ab8c6a6e822f3c36781d79e8824e9"title="Total size of the virtual block.">VmaVirtualBlockCreateInfo::size</a></li>
<li><aclass="el"href="struct_vma_virtual_allocation_create_info.html#aae08752b86817abd0d944c6025dc603e"title="Size of the allocation.">VmaVirtualAllocationCreateInfo::size</a> and <aclass="el"href="struct_vma_virtual_allocation_create_info.html#a9d19709872fc1904a105079e1c885821"title="Required alignment of the allocation. Optional.">VmaVirtualAllocationCreateInfo::alignment</a></li>
<li>Using offset returned by <aclass="el"href="group__group__virtual.html#ga6b7cdcc1c3e5103c323fedc4e1319e01"title="Allocates new virtual allocation inside given VmaVirtualBlock.">vmaVirtualAllocate()</a> or in <aclass="el"href="struct_vma_virtual_allocation_info.html#accb40a8205f49ccca3de975da7d1a2b5"title="Offset of the allocation.">VmaVirtualAllocationInfo::offset</a></li>
<p>You can obtain statistics of a virtual block using <aclass="el"href="group__group__virtual.html#ga95169b4730e94757897470086ec2768a"title="Calculates and returns statistics about virtual allocations and memory usage in given VmaVirtualBlock...">vmaCalculateVirtualBlockStats()</a>. The function fills structure <aclass="el"href="struct_vma_stat_info.html"title="Calculated statistics of memory usage in entire allocator.">VmaStatInfo</a> - same as used by the normal Vulkan memory allocator. Example:</p>
<divclass="ttc"id="agroup__group__virtual_html_ga95169b4730e94757897470086ec2768a"><divclass="ttname"><ahref="group__group__virtual.html#ga95169b4730e94757897470086ec2768a">vmaCalculateVirtualBlockStats</a></div><divclass="ttdeci">void vmaCalculateVirtualBlockStats(VmaVirtualBlock virtualBlock, VmaStatInfo *pStatInfo)</div><divclass="ttdoc">Calculates and returns statistics about virtual allocations and memory usage in given VmaVirtualBlock...</div></div>
<divclass="ttc"id="astruct_vma_stat_info_html"><divclass="ttname"><ahref="struct_vma_stat_info.html">VmaStatInfo</a></div><divclass="ttdoc">Calculated statistics of memory usage in entire allocator.</div><divclass="ttdef"><b>Definition:</b> vk_mem_alloc.h:1066</div></div>
<divclass="ttc"id="astruct_vma_stat_info_html_a537741e4d5cdddc1c0ab95ec650afaff"><divclass="ttname"><ahref="struct_vma_stat_info.html#a537741e4d5cdddc1c0ab95ec650afaff">VmaStatInfo::allocationCount</a></div><divclass="ttdeci">uint32_t allocationCount</div><divclass="ttdoc">Number of VmaAllocation allocation objects allocated.</div><divclass="ttdef"><b>Definition:</b> vk_mem_alloc.h:1070</div></div>
<divclass="ttc"id="astruct_vma_stat_info_html_ab0c6c73837e5a70c749fbd4f6064895a"><divclass="ttname"><ahref="struct_vma_stat_info.html#ab0c6c73837e5a70c749fbd4f6064895a">VmaStatInfo::usedBytes</a></div><divclass="ttdeci">VkDeviceSize usedBytes</div><divclass="ttdoc">Total number of bytes occupied by all allocations.</div><divclass="ttdef"><b>Definition:</b> vk_mem_alloc.h:1074</div></div>
</div><!-- fragment --><p>You can also request a full list of allocations and free regions as a string in JSON format by calling <aclass="el"href="group__group__stats.html#ga52d810e1222c592e5d80556ad005f1e6"title="Builds and returns a null-terminated string in JSON format with information about given VmaVirtualBlo...">vmaBuildVirtualBlockStatsString()</a>. Returned string must be later freed using <aclass="el"href="group__group__stats.html#ga47fb8d8aa69df4a7c23a9719b4080623"title="Frees a string returned by vmaBuildVirtualBlockStatsString().">vmaFreeVirtualBlockStatsString()</a>. The format of this string differs from the one returned by the main Vulkan allocator, but it is similar.</p>
<p>The "virtual allocator" functionality is implemented on a level of individual memory blocks. Keeping track of a whole collection of blocks, allocating new ones when out of free space, deleting empty ones, and deciding which one to try first for a new allocation must be implemented by the user.</p>
<p>Alternative allocation algorithms are supported, just like in custom pools of the real GPU memory. See enum <aclass="el"href="group__group__virtual.html#ga88bcf8c1cd3bb1610ff7343811c65bca"title="Flags to be passed as VmaVirtualBlockCreateInfo::flags.">VmaVirtualBlockCreateFlagBits</a> to learn how to specify them (e.g. <aclass="el"href="group__group__virtual.html#gga88bcf8c1cd3bb1610ff7343811c65bcaae6423e2fa2f3c9211b21c819e3f10f96"title="Enables alternative, linear allocation algorithm in this virtual block.">VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT</a>). You can find their description in chapter <aclass="el"href="custom_memory_pools.html">Custom memory pools</a>. Allocation strategies are also supported. See enum <aclass="el"href="group__group__virtual.html#ga2e9c64d405b14156fea7e10c4ad06cb6"title="Flags to be passed as VmaVirtualAllocationCreateInfo::flags.">VmaVirtualAllocationCreateFlagBits</a> to learn how to specify them (e.g. <aclass="el"href="group__group__virtual.html#gga2e9c64d405b14156fea7e10c4ad06cb6a562d10a46012719d33167d3dc5dbbf9b"title="Allocation strategy that tries to minimize allocation time.">VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT</a>).</p>
<p>Following features are supported only by the allocator of the real GPU memory and not by virtual allocations: buffer-image granularity, <code>VMA_DEBUG_MARGIN</code>, <code>VMA_MIN_ALIGNMENT</code>. </p>