blob: 26e13ae04694d5218cc0836b9106b2d2e4932610 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.2"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Vulkan Memory Allocator: Defragmentation</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">Vulkan Memory Allocator
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.2 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="index.html">Vulkan Memory Allocator</a></li> </ul>
</div>
</div><!-- top -->
<div><div class="header">
<div class="headertitle"><div class="title">Defragmentation </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p >Interleaved allocations and deallocations of many objects of varying size can cause fragmentation over time, which can lead to a situation where the library is unable to find a continuous range of free memory for a new allocation despite there is enough free space, just scattered across many small free ranges between existing allocations.</p>
<p >To mitigate this problem, you can use defragmentation feature. It doesn't happen automatically though and needs your cooperation, because VMA is a low level library that only allocates memory. It cannot recreate buffers and images in a new place as it doesn't remember the contents of <code>VkBufferCreateInfo</code> / <code>VkImageCreateInfo</code> structures. It cannot copy their contents as it doesn't record any commands to a command buffer.</p>
<p >Example:</p>
<div class="fragment"><div class="line"><a class="code hl_struct" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a> defragInfo = {};</div>
<div class="line">defragInfo.<a class="code hl_variable" href="struct_vma_defragmentation_info.html#a18dd2097d8ab2976cdc7dd3e7b978bd4">pool</a> = myPool;</div>
<div class="line">defragInfo.<a class="code hl_variable" href="struct_vma_defragmentation_info.html#a3e23080c978ecf3abb3180f5b2069da7">flags</a> = <a class="code hl_enumvalue" href="group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50ca2e6469bcf5a094776ceb5d118263f04b">VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT</a>;</div>
<div class="line"> </div>
<div class="line"><a class="code hl_struct" href="struct_vma_defragmentation_context.html">VmaDefragmentationContext</a> defragCtx;</div>
<div class="line">VkResult res = <a class="code hl_function" href="group__group__alloc.html#gac3335566858b45541fa9c0d7a6bbb57e">vmaBeginDefragmentation</a>(allocator, &amp;defragInfo, &amp;defragCtx);</div>
<div class="line"><span class="comment">// Check res...</span></div>
<div class="line"> </div>
<div class="line"><span class="keywordflow">for</span>(;;)</div>
<div class="line">{</div>
<div class="line"> <a class="code hl_struct" href="struct_vma_defragmentation_pass_move_info.html">VmaDefragmentationPassMoveInfo</a> pass;</div>
<div class="line"> res = <a class="code hl_function" href="group__group__alloc.html#ga980d7da2ce3b1fd5c8b8476bc362cc00">vmaBeginDefragmentationPass</a>(allocator, defragCtx, &amp;pass);</div>
<div class="line"> <span class="keywordflow">if</span>(res == VK_SUCCESS)</div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span>(res == VK_INCOMPLETE)</div>
<div class="line"> {</div>
<div class="line"> <span class="keywordflow">for</span>(uint32_t i = 0; i &lt; pass.<a class="code hl_variable" href="struct_vma_defragmentation_pass_move_info.html#a1b3e18c23f9691f35baf183e615c4408">moveCount</a>; ++i)</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">//- Inspect pass.pMoves[i].srcAllocation, identify what buffer or image it represents.</span></div>
<div class="line"> <span class="comment">//- Recreate and bind this buffer or image at pass.pMoves[i].dstMemory, pass.pMoves[i].dstOffset.</span></div>
<div class="line"> <span class="comment">//- Issue a vkCmdCopyBuffer/vkCmdCopyImage to copy its content to the new place.</span></div>
<div class="line"> }</div>
<div class="line"> <span class="comment">//- Make sure the copy commands finished executing.</span></div>
<div class="line"> <span class="comment">//- Update appropriate descriptors to point to the new places.</span></div>
<div class="line"> res = <a class="code hl_function" href="group__group__alloc.html#gaded05a445742a00718ee766144c5c226">vmaEndDefragmentationPass</a>(allocator, defragCtx, &amp;pass);</div>
<div class="line"> <span class="keywordflow">if</span>(res == VK_SUCCESS)</div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span>(res != VK_INCOMPLETE)</div>
<div class="line"> <span class="comment">// Handle error...</span></div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">else</span></div>
<div class="line"> <span class="comment">// Handle error...</span></div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><a class="code hl_function" href="group__group__alloc.html#ga729a594b45ae1681096940a44f3eb174">vmaEndDefragmentation</a>(allocator, defragCtx, <span class="keyword">nullptr</span>);</div>
<div class="ttc" id="agroup__group__alloc_html_ga729a594b45ae1681096940a44f3eb174"><div class="ttname"><a href="group__group__alloc.html#ga729a594b45ae1681096940a44f3eb174">vmaEndDefragmentation</a></div><div class="ttdeci">VkResult vmaEndDefragmentation(VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationStats *pStats)</div><div class="ttdoc">Ends defragmentation process.</div></div>
<div class="ttc" id="agroup__group__alloc_html_ga980d7da2ce3b1fd5c8b8476bc362cc00"><div class="ttname"><a href="group__group__alloc.html#ga980d7da2ce3b1fd5c8b8476bc362cc00">vmaBeginDefragmentationPass</a></div><div class="ttdeci">VkResult vmaBeginDefragmentationPass(VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationPassMoveInfo *pPassInfo)</div><div class="ttdoc">Starts single defragmentation pass.</div></div>
<div class="ttc" id="agroup__group__alloc_html_gac3335566858b45541fa9c0d7a6bbb57e"><div class="ttname"><a href="group__group__alloc.html#gac3335566858b45541fa9c0d7a6bbb57e">vmaBeginDefragmentation</a></div><div class="ttdeci">VkResult vmaBeginDefragmentation(VmaAllocator allocator, const VmaDefragmentationInfo *pInfo, VmaDefragmentationContext *pContext)</div><div class="ttdoc">Begins defragmentation process.</div></div>
<div class="ttc" id="agroup__group__alloc_html_gaded05a445742a00718ee766144c5c226"><div class="ttname"><a href="group__group__alloc.html#gaded05a445742a00718ee766144c5c226">vmaEndDefragmentationPass</a></div><div class="ttdeci">VkResult vmaEndDefragmentationPass(VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationPassMoveInfo *pPassInfo)</div><div class="ttdoc">Ends single defragmentation pass.</div></div>
<div class="ttc" id="agroup__group__alloc_html_gga6552a65b71d16f378c6994b3ceaef50ca2e6469bcf5a094776ceb5d118263f04b"><div class="ttname"><a href="group__group__alloc.html#gga6552a65b71d16f378c6994b3ceaef50ca2e6469bcf5a094776ceb5d118263f04b">VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT</a></div><div class="ttdeci">@ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:707</div></div>
<div class="ttc" id="astruct_vma_defragmentation_context_html"><div class="ttname"><a href="struct_vma_defragmentation_context.html">VmaDefragmentationContext</a></div><div class="ttdoc">An opaque object that represents started defragmentation process.</div></div>
<div class="ttc" id="astruct_vma_defragmentation_info_html"><div class="ttname"><a href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a></div><div class="ttdoc">Parameters for defragmentation.</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1401</div></div>
<div class="ttc" id="astruct_vma_defragmentation_info_html_a18dd2097d8ab2976cdc7dd3e7b978bd4"><div class="ttname"><a href="struct_vma_defragmentation_info.html#a18dd2097d8ab2976cdc7dd3e7b978bd4">VmaDefragmentationInfo::pool</a></div><div class="ttdeci">VmaPool pool</div><div class="ttdoc">Custom pool to be defragmented.</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1408</div></div>
<div class="ttc" id="astruct_vma_defragmentation_info_html_a3e23080c978ecf3abb3180f5b2069da7"><div class="ttname"><a href="struct_vma_defragmentation_info.html#a3e23080c978ecf3abb3180f5b2069da7">VmaDefragmentationInfo::flags</a></div><div class="ttdeci">VmaDefragmentationFlags flags</div><div class="ttdoc">Use combination of VmaDefragmentationFlagBits.</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1403</div></div>
<div class="ttc" id="astruct_vma_defragmentation_pass_move_info_html"><div class="ttname"><a href="struct_vma_defragmentation_pass_move_info.html">VmaDefragmentationPassMoveInfo</a></div><div class="ttdoc">Parameters for incremental defragmentation steps.</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1441</div></div>
<div class="ttc" id="astruct_vma_defragmentation_pass_move_info_html_a1b3e18c23f9691f35baf183e615c4408"><div class="ttname"><a href="struct_vma_defragmentation_pass_move_info.html#a1b3e18c23f9691f35baf183e615c4408">VmaDefragmentationPassMoveInfo::moveCount</a></div><div class="ttdeci">uint32_t moveCount</div><div class="ttdoc">Number of elements in the pMoves array.</div><div class="ttdef"><b>Definition:</b> vk_mem_alloc.h:1443</div></div>
</div><!-- fragment --><p >You can defragment a specific custom pool by setting <a class="el" href="struct_vma_defragmentation_info.html#a18dd2097d8ab2976cdc7dd3e7b978bd4" title="Custom pool to be defragmented.">VmaDefragmentationInfo::pool</a> (like in the example above) or all the default pools by setting this member to null.</p>
<p >Unlike in previous iterations of the defragmentation API, there is no list of "movable" allocations passed as a parameter. Defragmentation algorithm tries to move all suitable allocations. You can, however, refuse to move some of them inside a defragmentation pass, by setting <code>pass.pMoves[i].operation</code> to <a class="el" href="group__group__alloc.html#ggada9e3861caf96f08894b0bcc160ec257ad25bc6f816b226b4fd5170e845f218d2" title="Set this value if you cannot move the allocation. New place reserved dstMemory + dstOffset will be fr...">VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE</a>. This is not recommended and may result in suboptimal packing of the allocations after defragmentation. If you cannot ensure any allocation can be moved, it is better to keep movable allocations separate in a custom pool.</p>
<p >You can also decide to destroy an allocation instead of moving it. You should then set <code>pass.pMoves[i].operation</code> to <a class="el" href="group__group__alloc.html#ggada9e3861caf96f08894b0bcc160ec257a9786f8492a9be2c03bd26395e352ab85" title="Set this value if you decide to abandon the allocation and you destroyed the buffer/image....">VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY</a>.</p>
<p >You can perform the defragmentation incrementally to limit the number of allocations and bytes to be moved in each pass, e.g. to call it in sync with render frames and not to experience too big hitches. See members: <a class="el" href="struct_vma_defragmentation_info.html#a637ada77b02179a27fa92290000afac4" title="Maximum numbers of bytes that can be copied during single pass, while moving allocations to different...">VmaDefragmentationInfo::maxBytesPerPass</a>, <a class="el" href="struct_vma_defragmentation_info.html#ac2db29d309bebc4f7d55041416e9694b" title="Maximum number of allocations that can be moved during single pass to a different place.">VmaDefragmentationInfo::maxAllocationsPerPass</a>.</p>
<p >It is also safe to perform the defragmentation asynchronously to render frames and other Vulkan and VMA usage, possibly from multiple threads, with the exception that allocations returned in <a class="el" href="struct_vma_defragmentation_pass_move_info.html#adfa7a4994afd9b940e7f1dfaf436a725" title="Array of moves to be performed by the user in the current defragmentation pass.">VmaDefragmentationPassMoveInfo::pMoves</a> shouldn't be destroyed until the defragmentation pass is ended.</p>
<dl class="section note"><dt>Note</dt><dd>Defragmentation is not supported in custom pools created with <a class="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>
</div></div><!-- contents -->
</div><!-- PageDoc -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.2
</small></address>
</body>
</html>