You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+3-1Lines changed: 3 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -26,7 +26,9 @@ Major changes:
26
26
27
27
Minor changes:
28
28
29
-
- Changed behavior of custom pools: `VmaPoolCreateInfo::blockSize` = 0 (default) now means that pool may use variable block sizes, just like default pools do.
29
+
- Changes in custom pools:
30
+
- Added new structure member `VmaPoolStats::blockCount`.
31
+
- Changed behavior of `VmaPoolCreateInfo::blockSize` = 0 (default) - it now means that pool may use variable block sizes, just like default pools do.
30
32
- Improved logic of `vmaFindMemoryTypeIndex` for some cases, especially integrated GPUs.
31
33
- VulkanSample application: Removed dependency on external library MathFu. Added own vector and matrix structures.
32
34
- Code changes that improve compatibility with various platforms, including: Visual Studio 2012, 32-bit code, C compilers.
<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.</p>
104
-
<p>Pools with linear algorithm must have only 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.</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="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568" title="Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). ">vmaFreeMemory()</a> or <aclass="el" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77" 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>
<li>Second, "upper" one, growing down from the end towards lower offsets.</li>
123
124
</ul>
124
125
<p>To make allocation from upper stack, add flag <aclass="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a42ba3a2d2c7117953210b7c3ef8da0df">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>
125
-
<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>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>
130
+
<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>
<imgsrc="../gfx/Linear_allocator_6_ring_buffer_lost.png" alt="Ring buffer with lost allocations"/>
138
140
</div>
139
-
</div></div><!-- contents -->
141
+
<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>
142
+
</div></div><!-- contents -->
140
143
<!-- start footer part -->
141
144
<hrclass="footer"/><addressclass="footer"><small>
142
145
Generated by  <ahref="http://www.doxygen.org/index.html">
Copy file name to clipboardExpand all lines: docs/html/lost_allocations.html
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -77,7 +77,7 @@
77
77
<p><b>Q: How do you inform the library when new frame starts?</b></p>
78
78
<p>You need to call function <aclass="el" href="vk__mem__alloc_8h.html#ade56bf8dc9f5a5eaddf5f119ed525236" title="Sets index of the current frame. ">vmaSetCurrentFrameIndex()</a>.</p>
79
79
<p>Example code:</p>
80
-
<divclass="fragment"><divclass="line"><spanclass="keyword">struct </span>MyBuffer</div><divclass="line">{</div><divclass="line"> VkBuffer m_Buf = <spanclass="keyword">nullptr</span>;</div><divclass="line"><aclass="code" href="struct_vma_allocation.html">VmaAllocation</a> m_Alloc = <spanclass="keyword">nullptr</span>;</div><divclass="line"></div><divclass="line"><spanclass="comment">// Called when the buffer is really needed in the current frame.</span></div><divclass="line"><spanclass="keywordtype">void</span> EnsureBuffer();</div><divclass="line">};</div><divclass="line"></div><divclass="line"><spanclass="keywordtype">void</span> MyBuffer::EnsureBuffer()</div><divclass="line">{</div><divclass="line"><spanclass="comment">// Buffer has been created.</span></div><divclass="line"><spanclass="keywordflow">if</span>(m_Buf != VK_NULL_HANDLE)</div><divclass="line"> {</div><divclass="line"><spanclass="comment">// Check if its allocation is not lost + mark it as used in current frame.</span></div><divclass="line"><spanclass="keywordflow">if</span>(<aclass="code" href="vk__mem__alloc_8h.html#a43d8ba9673c846f049089a5029d5c73a">vmaTouchAllocation</a>(allocator, m_Alloc))</div><divclass="line"> {</div><divclass="line"><spanclass="comment">// It's all OK - safe to use m_Buf.</span></div><divclass="line"><spanclass="keywordflow">return</span>;</div><divclass="line"> }</div><divclass="line"> }</div><divclass="line"></div><divclass="line"><spanclass="comment">// Buffer not yet exists or lost - destroy and recreate it.</span></div><divclass="line"></div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a>(allocator, m_Buf, m_Alloc);</div><divclass="line"></div><divclass="line"> VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><divclass="line"> bufCreateInfo.size = 1024;</div><divclass="line"> bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><divclass="line"></div><divclass="line"><aclass="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><divclass="line"> allocCreateInfo.<aclass="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <aclass="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>;</div><divclass="line"> allocCreateInfo.<aclass="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = <aclass="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> |</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a>;</div><divclass="line"></div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &bufCreateInfo, &allocCreateInfo, &m_Buf, &m_Alloc, <spanclass="keyword">nullptr</span>);</div><divclass="line">}</div></div><!-- fragment --><p>When using lost allocations, you may see some Vulkan validation layer warnings about overlapping regions of memory bound to different kinds of buffers and images. This is still valid as long as you implement proper handling of lost allocations (like in the example above) and don't use them.</p>
80
+
<divclass="fragment"><divclass="line"><spanclass="keyword">struct </span>MyBuffer</div><divclass="line">{</div><divclass="line"> VkBuffer m_Buf = <spanclass="keyword">nullptr</span>;</div><divclass="line"><aclass="code" href="struct_vma_allocation.html">VmaAllocation</a> m_Alloc = <spanclass="keyword">nullptr</span>;</div><divclass="line"></div><divclass="line"><spanclass="comment">// Called when the buffer is really needed in the current frame.</span></div><divclass="line"><spanclass="keywordtype">void</span> EnsureBuffer();</div><divclass="line">};</div><divclass="line"></div><divclass="line"><spanclass="keywordtype">void</span> MyBuffer::EnsureBuffer()</div><divclass="line">{</div><divclass="line"><spanclass="comment">// Buffer has been created.</span></div><divclass="line"><spanclass="keywordflow">if</span>(m_Buf != VK_NULL_HANDLE)</div><divclass="line"> {</div><divclass="line"><spanclass="comment">// Check if its allocation is not lost + mark it as used in current frame.</span></div><divclass="line"><spanclass="keywordflow">if</span>(<aclass="code" href="vk__mem__alloc_8h.html#a43d8ba9673c846f049089a5029d5c73a">vmaTouchAllocation</a>(allocator, m_Alloc))</div><divclass="line"> {</div><divclass="line"><spanclass="comment">// It's all OK - safe to use m_Buf.</span></div><divclass="line"><spanclass="keywordflow">return</span>;</div><divclass="line"> }</div><divclass="line"> }</div><divclass="line"></div><divclass="line"><spanclass="comment">// Buffer not yet exists or lost - destroy and recreate it.</span></div><divclass="line"></div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a>(allocator, m_Buf, m_Alloc);</div><divclass="line"></div><divclass="line"> VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><divclass="line"> bufCreateInfo.size = 1024;</div><divclass="line"> bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><divclass="line"></div><divclass="line"><aclass="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><divclass="line"> allocCreateInfo.<aclass="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <aclass="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>;</div><divclass="line"> allocCreateInfo.<aclass="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT |</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a>;</div><divclass="line"></div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &bufCreateInfo, &allocCreateInfo, &m_Buf, &m_Alloc, <spanclass="keyword">nullptr</span>);</div><divclass="line">}</div></div><!-- fragment --><p>When using lost allocations, you may see some Vulkan validation layer warnings about overlapping regions of memory bound to different kinds of buffers and images. This is still valid as long as you implement proper handling of lost allocations (like in the example above) and don't use them.</p>
81
81
<p>You can create an allocation that is already in lost state from the beginning using function <aclass="el" href="vk__mem__alloc_8h.html#ae5c9657d9e94756269145b01c05d16f1" title="Creates new allocation that is in lost state from the beginning. ">vmaCreateLostAllocation()</a>. It may be useful if you need a "dummy" allocation that is not null.</p>
82
82
<p>You can call function <aclass="el" href="vk__mem__alloc_8h.html#a736bd6cbda886f36c891727e73bd4024" title="Marks all allocations in given pool as lost if they are not used in current frame or VmaPoolCreateInf...">vmaMakePoolAllocationsLost()</a> to set all eligible allocations in a specified custom pool to lost state. Allocations that have been "touched" in current frame or <aclass="el" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa" title="Maximum number of additional frames that are in use at the same time as current frame. ">VmaPoolCreateInfo::frameInUseCount</a> frames back cannot become lost.</p>
83
83
<p><b>Q: Can I touch allocation that cannot become lost?</b></p>
Copy file name to clipboardExpand all lines: docs/html/quick_start.html
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -76,6 +76,7 @@
76
76
<li>In exacly one CPP file define following macro before this include. It enables also internal definitions.</li>
77
77
</ol>
78
78
<divclass="fragment"><divclass="line"><spanclass="preprocessor">#define VMA_IMPLEMENTATION</span></div><divclass="line"><spanclass="preprocessor">#include "vk_mem_alloc.h"</span></div></div><!-- fragment --><p>It may be a good idea to create dedicated CPP file just for this purpose.</p>
79
+
<p>Please note that this library includes header <code><vulkan/vulkan.h></code>, which in turn includes <code><windows.h></code> on Windows. If you need some specific macros defined before including these headers (like <code>NOMINMAX</code>, <code>WIN32_LEAN_AND_MEAN</code>, or <code>WINVER</code> for Windows, <code>VK_USE_PLATFORM_WIN32_KHR</code> for Vulkan), you must define them before every <code>#include</code> of this library.</p>
0 commit comments