Skip to content

Commit 7ce9630

Browse files
Improved documentation chapters: Defragmentation, vmaDefragment(), Features not supported.
1 parent 6aa6255 commit 7ce9630

9 files changed

Lines changed: 255 additions & 320 deletions

docs/html/defragmentation.html

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,13 @@
7070
</div><!--header-->
7171
<div class="contents">
7272
<div class="textblock"><p>Interleaved allocations and deallocations of many objects of varying size can cause fragmentation, 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>
73-
<p>To mitigate this problem, you can use <a class="el" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a>. Given set of allocations, this function can move them to compact used memory, ensure more continuous free space and possibly also free some <code>VkDeviceMemory</code>. It can work only on allocations made from memory type that is <code>HOST_VISIBLE</code>. Allocations are modified to point to the new <code>VkDeviceMemory</code> and offset. Data in this memory is also <code>memmove</code>-ed to the new place. However, if you have images or buffers bound to these allocations (and you certainly do), you need to destroy, recreate, and bind them to the new place in memory.</p>
74-
<p>For further details and example code, see documentation of function <a class="el" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a>. </p>
73+
<p>To mitigate this problem, you can use <a class="el" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a>. Given set of allocations, this function can move them to compact used memory, ensure more continuous free space and possibly also free some <code>VkDeviceMemory</code>. Currently it can work only on allocations made from memory type that is <code>HOST_VISIBLE</code> and <code>HOST_COHERENT</code>. Allocations are modified to point to the new <code>VkDeviceMemory</code> and offset. Data in this memory is also <code>memmove</code>-ed to the new place. However, if you have images or buffers bound to these allocations (and you certainly do), you need to destroy, recreate, and bind them to the new place in memory.</p>
74+
<p>After allocation has been moved, its <a class="el" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67" title="Handle to Vulkan memory object. ">VmaAllocationInfo::deviceMemory</a> and/or <a class="el" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268" title="Offset into deviceMemory object to the beginning of this allocation, in bytes. (deviceMemory, offset) pair is unique to this allocation. ">VmaAllocationInfo::offset</a> changes. You must query them again using <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation and atomically marks it as used in current fra...">vmaGetAllocationInfo()</a> if you need them.</p>
75+
<p>If an allocation has been moved, data in memory is copied to new place automatically, but if it was bound to a buffer or an image, you must destroy that object yourself, create new one and bind it to the new memory pointed by the allocation. You must use <code>vkDestroyBuffer()</code>, <code>vkDestroyImage()</code>, <code>vkCreateBuffer()</code>, <code>vkCreateImage()</code> for that purpose and NOT <a class="el" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77" title="Destroys Vulkan buffer and frees allocated memory. ">vmaDestroyBuffer()</a>, <a class="el" href="vk__mem__alloc_8h.html#ae50d2cb3b4a3bfd4dd40987234e50e7e" title="Destroys Vulkan image and frees allocated memory. ">vmaDestroyImage()</a>, <a class="el" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer()</a>, <a class="el" href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73" title="Function similar to vmaCreateBuffer(). ">vmaCreateImage()</a>! Example:</p>
76+
<div class="fragment"><div class="line">VkDevice device = ...;</div><div class="line"><a class="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator = ...;</div><div class="line">std::vector&lt;VkBuffer&gt; buffers = ...;</div><div class="line">std::vector&lt;VmaAllocation&gt; allocations = ...;</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">size_t</span> allocCount = allocations.size();</div><div class="line"></div><div class="line">std::vector&lt;VkBool32&gt; allocationsChanged(allocCount);</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb">vmaDefragment</a>(allocator, allocations.data(), allocCount, allocationsChanged.data(), <span class="keyword">nullptr</span>, <span class="keyword">nullptr</span>);</div><div class="line"></div><div class="line"><span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; allocCount; ++i)</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span>(allocationsChanged[i])</div><div class="line"> {</div><div class="line"> <span class="comment">// Destroy buffers that is immutably bound to memory region which is no longer valid.</span></div><div class="line"> vkDestroyBuffer(device, buffers[i], <span class="keyword">nullptr</span>);</div><div class="line"></div><div class="line"> <span class="comment">// Create new buffer with same parameters.</span></div><div class="line"> VkBufferCreateInfo bufferInfo = ...;</div><div class="line"> vkCreateBuffer(device, &amp;bufferInfo, <span class="keyword">nullptr</span>, &amp;buffers[i]);</div><div class="line"> </div><div class="line"> <span class="comment">// You can make dummy call to vkGetBufferMemoryRequirements here to silence validation layer warning.</span></div><div class="line"> </div><div class="line"> <span class="comment">// Bind new buffer with new memory region. Data contained in it is already there.</span></div><div class="line"> <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><div class="line"> <a class="code" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b">vmaGetAllocationInfo</a>(allocator, allocations[i], &amp;allocInfo);</div><div class="line"> vkBindBufferMemory(device, buffers[i], allocInfo.<a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a>, allocInfo.<a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a>);</div><div class="line"> }</div><div class="line">}</div></div><!-- fragment --><p>Please don't expect memory to be fully compacted after defragmentation. Algorithms inside are based on some heuristics that try to maximize number of Vulkan memory blocks to make totally empty to release them, as well as to maximimze continuous empty space inside remaining blocks, while minimizing the number and size of allocations that needs to be moved. Some fragmentation still remains after this call. This is normal.</p>
77+
<p>If you defragment allocations bound to images, these images should be created with <code>VK_IMAGE_CREATE_ALIAS_BIT</code> flag, to make sure that new image created with same parameters and pointing to data copied to another memory region will interpret its contents consistently. Otherwise you may experience corrupted data on some implementations, e.g. due to different pixel swizzling used internally by the graphics driver.</p>
78+
<p>If you defragment allocations bound to images, new images to be bound to new memory region after defragmentation should be created with <code>VK_IMAGE_LAYOUT_PREINITIALIZED</code> and then transitioned to their original layout from before defragmentation using an image memory barrier.</p>
79+
<p>For further details, see documentation of function <a class="el" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a>. </p>
7580
</div></div><!-- contents -->
7681
<!-- start footer part -->
7782
<hr class="footer"/><address class="footer"><small>

docs/html/general_considerations.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ <h1><a class="anchor" id="general_considerations_features_not_supported"></a>
110110
Features not supported</h1>
111111
<p>Features deliberately excluded from the scope of this library:</p>
112112
<ul>
113-
<li>Sparse resources.</li>
113+
<li>Support for sparse binding and sparse residency. You can still use these features (when supported by the device) with VMA. You just need to do it yourself. Any explicit support for sparse binding/residency would rather require another, higher-level library on top of VMA.</li>
114114
<li>Data transfer - issuing commands that transfer data between buffers or images, any usage of <code>VkCommandList</code> or <code>VkQueue</code> and related synchronization is responsibility of the user.</li>
115115
<li>Allocations for imported/exported external memory. They tend to require explicit memory type index and dedicated allocation anyway, so they don't interact with main features of this library. Such special purpose allocations should be made manually, using <code>vkCreateBuffer()</code> and <code>vkAllocateMemory()</code>.</li>
116116
<li>Support for any programming languages other than C/C++. Bindings to other languages are welcomed as external projects. </li>

docs/html/globals.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ <h3><a id="index_v"></a>- v -</h3><ul>
328328
: <a class="el" href="vk__mem__alloc_8h.html#a2e5612d871d64c5624087b837a338c34">vk_mem_alloc.h</a>
329329
</li>
330330
<li>VmaRecordFlagBits
331-
: <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">vk_mem_alloc.h</a>
331+
: <a class="el" href="vk__mem__alloc_8h.html#ade20b626a6635ce1bf30ea53dea774e4">vk_mem_alloc.h</a>
332332
</li>
333333
<li>VmaRecordFlags
334334
: <a class="el" href="vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828">vk_mem_alloc.h</a>

docs/html/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
<div class="title">Vulkan Memory Allocator </div> </div>
6666
</div><!--header-->
6767
<div class="contents">
68-
<div class="textblock"><p><b>Version 2.1.0</b> (2018-09-10)</p>
68+
<div class="textblock"><p><b>Version 2.1.1-development</b> (2018-09-24)</p>
6969
<p>Copyright (c) 2017-2018 Advanced Micro Devices, Inc. All rights reserved. <br />
7070
License: MIT</p>
7171
<p>Documentation of all members: <a class="el" href="vk__mem__alloc_8h.html">vk_mem_alloc.h</a></p>

docs/html/search/all_10.js

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)