Added functions: vmaAllocateMemoryPages, vmaFreeMemoryPages to create and destroy multiple allocations at once.

This commit is contained in:
Adam Sawicki 2018-10-03 15:26:22 +02:00
parent 51fa96660e
commit d062b784d3
9 changed files with 527 additions and 111 deletions

View File

@ -192,6 +192,9 @@ $(function() {
<li>vmaAllocateMemoryForImage()
: <a class="el" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb">vk_mem_alloc.h</a>
</li>
<li>vmaAllocateMemoryPages()
: <a class="el" href="vk__mem__alloc_8h.html#ad37e82e492b3de38fc3f4cffd9ad0ae1">vk_mem_alloc.h</a>
</li>
<li>VmaAllocationCreateFlagBits
: <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597">vk_mem_alloc.h</a>
</li>
@ -285,6 +288,9 @@ $(function() {
<li>vmaFreeMemory()
: <a class="el" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568">vk_mem_alloc.h</a>
</li>
<li>vmaFreeMemoryPages()
: <a class="el" href="vk__mem__alloc_8h.html#ab9e709de044c5d8476bea77a4e755840">vk_mem_alloc.h</a>
</li>
<li>vmaFreeStatsString()
: <a class="el" href="vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288">vk_mem_alloc.h</a>
</li>
@ -328,7 +334,7 @@ $(function() {
: <a class="el" href="vk__mem__alloc_8h.html#a2e5612d871d64c5624087b837a338c34">vk_mem_alloc.h</a>
</li>
<li>VmaRecordFlagBits
: <a class="el" href="vk__mem__alloc_8h.html#ade20b626a6635ce1bf30ea53dea774e4">vk_mem_alloc.h</a>
: <a class="el" href="vk__mem__alloc_8h.html#a4dd2c44642312a147a4e93373a6e64d2">vk_mem_alloc.h</a>
</li>
<li>VmaRecordFlags
: <a class="el" href="vk__mem__alloc_8h.html#af3929a1a4547c592fc0b0e55ef452828">vk_mem_alloc.h</a>

View File

@ -73,6 +73,9 @@ $(function() {
<li>vmaAllocateMemoryForImage()
: <a class="el" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb">vk_mem_alloc.h</a>
</li>
<li>vmaAllocateMemoryPages()
: <a class="el" href="vk__mem__alloc_8h.html#ad37e82e492b3de38fc3f4cffd9ad0ae1">vk_mem_alloc.h</a>
</li>
<li>vmaBindBufferMemory()
: <a class="el" href="vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470">vk_mem_alloc.h</a>
</li>
@ -136,6 +139,9 @@ $(function() {
<li>vmaFreeMemory()
: <a class="el" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568">vk_mem_alloc.h</a>
</li>
<li>vmaFreeMemoryPages()
: <a class="el" href="vk__mem__alloc_8h.html#ab9e709de044c5d8476bea77a4e755840">vk_mem_alloc.h</a>
</li>
<li>vmaFreeStatsString()
: <a class="el" href="vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288">vk_mem_alloc.h</a>
</li>

View File

@ -56,6 +56,7 @@ var searchData=
['vmaallocatememory',['vmaAllocateMemory',['../vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8',1,'vk_mem_alloc.h']]],
['vmaallocatememoryforbuffer',['vmaAllocateMemoryForBuffer',['../vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b',1,'vk_mem_alloc.h']]],
['vmaallocatememoryforimage',['vmaAllocateMemoryForImage',['../vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb',1,'vk_mem_alloc.h']]],
['vmaallocatememorypages',['vmaAllocateMemoryPages',['../vk__mem__alloc_8h.html#ad37e82e492b3de38fc3f4cffd9ad0ae1',1,'vk_mem_alloc.h']]],
['vmaallocation',['VmaAllocation',['../struct_vma_allocation.html',1,'']]],
['vmaallocationcreateflagbits',['VmaAllocationCreateFlagBits',['../vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597',1,'VmaAllocationCreateFlagBits():&#160;vk_mem_alloc.h'],['../vk__mem__alloc_8h.html#abf6bf6748c7a9fe7ce5b7835c0f56af4',1,'VmaAllocationCreateFlagBits():&#160;vk_mem_alloc.h']]],
['vmaallocationcreateflags',['VmaAllocationCreateFlags',['../vk__mem__alloc_8h.html#a5225e5e11f8376f6a31a1791f3d6e817',1,'vk_mem_alloc.h']]],
@ -89,6 +90,7 @@ var searchData=
['vmafindmemorytypeindexforimageinfo',['vmaFindMemoryTypeIndexForImageInfo',['../vk__mem__alloc_8h.html#a088da83d8eaf3ce9056d9ea0b981d472',1,'vk_mem_alloc.h']]],
['vmaflushallocation',['vmaFlushAllocation',['../vk__mem__alloc_8h.html#abc34ee6f021f459aff885f3758c435de',1,'vk_mem_alloc.h']]],
['vmafreememory',['vmaFreeMemory',['../vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568',1,'vk_mem_alloc.h']]],
['vmafreememorypages',['vmaFreeMemoryPages',['../vk__mem__alloc_8h.html#ab9e709de044c5d8476bea77a4e755840',1,'vk_mem_alloc.h']]],
['vmafreestatsstring',['vmaFreeStatsString',['../vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288',1,'vk_mem_alloc.h']]],
['vmagetallocationinfo',['vmaGetAllocationInfo',['../vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b',1,'vk_mem_alloc.h']]],
['vmagetmemoryproperties',['vmaGetMemoryProperties',['../vk__mem__alloc_8h.html#ab88db292a17974f911182543fda52d19',1,'vk_mem_alloc.h']]],

View File

@ -3,6 +3,7 @@ var searchData=
['vmaallocatememory',['vmaAllocateMemory',['../vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8',1,'vk_mem_alloc.h']]],
['vmaallocatememoryforbuffer',['vmaAllocateMemoryForBuffer',['../vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b',1,'vk_mem_alloc.h']]],
['vmaallocatememoryforimage',['vmaAllocateMemoryForImage',['../vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb',1,'vk_mem_alloc.h']]],
['vmaallocatememorypages',['vmaAllocateMemoryPages',['../vk__mem__alloc_8h.html#ad37e82e492b3de38fc3f4cffd9ad0ae1',1,'vk_mem_alloc.h']]],
['vmabindbuffermemory',['vmaBindBufferMemory',['../vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470',1,'vk_mem_alloc.h']]],
['vmabindimagememory',['vmaBindImageMemory',['../vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5',1,'vk_mem_alloc.h']]],
['vmabuildstatsstring',['vmaBuildStatsString',['../vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0',1,'vk_mem_alloc.h']]],
@ -24,6 +25,7 @@ var searchData=
['vmafindmemorytypeindexforimageinfo',['vmaFindMemoryTypeIndexForImageInfo',['../vk__mem__alloc_8h.html#a088da83d8eaf3ce9056d9ea0b981d472',1,'vk_mem_alloc.h']]],
['vmaflushallocation',['vmaFlushAllocation',['../vk__mem__alloc_8h.html#abc34ee6f021f459aff885f3758c435de',1,'vk_mem_alloc.h']]],
['vmafreememory',['vmaFreeMemory',['../vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568',1,'vk_mem_alloc.h']]],
['vmafreememorypages',['vmaFreeMemoryPages',['../vk__mem__alloc_8h.html#ab9e709de044c5d8476bea77a4e755840',1,'vk_mem_alloc.h']]],
['vmafreestatsstring',['vmaFreeStatsString',['../vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288',1,'vk_mem_alloc.h']]],
['vmagetallocationinfo',['vmaGetAllocationInfo',['../vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b',1,'vk_mem_alloc.h']]],
['vmagetmemoryproperties',['vmaGetMemoryProperties',['../vk__mem__alloc_8h.html#ab88db292a17974f911182543fda52d19',1,'vk_mem_alloc.h']]],

View File

@ -302,6 +302,9 @@ Functions</h2></td></tr>
<tr class="memitem:abf28077dbf82d0908b8acbe8ee8dd9b8"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8">vmaAllocateMemory</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, const VkMemoryRequirements *pVkMemoryRequirements, const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *pCreateInfo, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> *pAllocation, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
<tr class="memdesc:abf28077dbf82d0908b8acbe8ee8dd9b8"><td class="mdescLeft">&#160;</td><td class="mdescRight">General purpose memory allocation. <a href="#abf28077dbf82d0908b8acbe8ee8dd9b8">More...</a><br /></td></tr>
<tr class="separator:abf28077dbf82d0908b8acbe8ee8dd9b8"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad37e82e492b3de38fc3f4cffd9ad0ae1"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#ad37e82e492b3de38fc3f4cffd9ad0ae1">vmaAllocateMemoryPages</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, const VkMemoryRequirements *pVkMemoryRequirements, const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *pCreateInfo, size_t allocationCount, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> *pAllocations, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
<tr class="memdesc:ad37e82e492b3de38fc3f4cffd9ad0ae1"><td class="mdescLeft">&#160;</td><td class="mdescRight">General purpose memory allocation for multiple allocation objects at once. <a href="#ad37e82e492b3de38fc3f4cffd9ad0ae1">More...</a><br /></td></tr>
<tr class="separator:ad37e82e492b3de38fc3f4cffd9ad0ae1"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a7fdf64415b6c3d83c454f28d2c53df7b"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, VkBuffer buffer, const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *pCreateInfo, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> *pAllocation, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
<tr class="separator:a7fdf64415b6c3d83c454f28d2c53df7b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0faa3f9e5fb233d29d1e00390650febb"><td class="memItemLeft" align="right" valign="top">VkResult&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb">vmaAllocateMemoryForImage</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, VkImage image, const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *pCreateInfo, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> *pAllocation, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
@ -310,6 +313,9 @@ Functions</h2></td></tr>
<tr class="memitem:a11f0fbc034fa81a4efedd73d61ce7568"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568">vmaFreeMemory</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</td></tr>
<tr class="memdesc:a11f0fbc034fa81a4efedd73d61ce7568"><td class="mdescLeft">&#160;</td><td class="mdescRight">Frees memory previously allocated using <a class="el" href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8" title="General purpose memory allocation. ">vmaAllocateMemory()</a>, <a class="el" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>, or <a class="el" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb" title="Function similar to vmaAllocateMemoryForBuffer(). ">vmaAllocateMemoryForImage()</a>. <a href="#a11f0fbc034fa81a4efedd73d61ce7568">More...</a><br /></td></tr>
<tr class="separator:a11f0fbc034fa81a4efedd73d61ce7568"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ab9e709de044c5d8476bea77a4e755840"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#ab9e709de044c5d8476bea77a4e755840">vmaFreeMemoryPages</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, size_t allocationCount, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> *pAllocations)</td></tr>
<tr class="memdesc:ab9e709de044c5d8476bea77a4e755840"><td class="mdescLeft">&#160;</td><td class="mdescRight">Frees memory and destroys multiple allocations. <a href="#ab9e709de044c5d8476bea77a4e755840">More...</a><br /></td></tr>
<tr class="separator:ab9e709de044c5d8476bea77a4e755840"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a86dd08aba8633bfa4ad0df2e76481d8b"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b">vmaGetAllocationInfo</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> allocation, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
<tr class="memdesc:a86dd08aba8633bfa4ad0df2e76481d8b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns current information about specified allocation and atomically marks it as used in current frame. <a href="#a86dd08aba8633bfa4ad0df2e76481d8b">More...</a><br /></td></tr>
<tr class="separator:a86dd08aba8633bfa4ad0df2e76481d8b"><td class="memSeparator" colspan="2">&#160;</td></tr>
@ -1022,7 +1028,7 @@ Functions</h2></td></tr>
</table>
</dd>
</dl>
<p>You should free the memory using <a class="el" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568" title="Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). ">vmaFreeMemory()</a>.</p>
<p>You should free the memory using <a class="el" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568" title="Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). ">vmaFreeMemory()</a> or <a class="el" href="vk__mem__alloc_8h.html#ab9e709de044c5d8476bea77a4e755840" title="Frees memory and destroys multiple allocations. ">vmaFreeMemoryPages()</a>.</p>
<p>It is recommended to use <a class="el" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>, <a class="el" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb" title="Function similar to vmaAllocateMemoryForBuffer(). ">vmaAllocateMemoryForImage()</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> instead whenever possible. </p>
</div>
@ -1127,6 +1133,76 @@ Functions</h2></td></tr>
<p>Function similar to <a class="el" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>. </p>
</div>
</div>
<a id="ad37e82e492b3de38fc3f4cffd9ad0ae1"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad37e82e492b3de38fc3f4cffd9ad0ae1">&#9670;&nbsp;</a></span>vmaAllocateMemoryPages()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">VkResult vmaAllocateMemoryPages </td>
<td>(</td>
<td class="paramtype"><a class="el" href="struct_vma_allocator.html">VmaAllocator</a>&#160;</td>
<td class="paramname"><em>allocator</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">const VkMemoryRequirements *&#160;</td>
<td class="paramname"><em>pVkMemoryRequirements</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *&#160;</td>
<td class="paramname"><em>pCreateInfo</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>allocationCount</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="struct_vma_allocation.html">VmaAllocation</a> *&#160;</td>
<td class="paramname"><em>pAllocations</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *&#160;</td>
<td class="paramname"><em>pAllocationInfo</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>General purpose memory allocation for multiple allocation objects at once. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramdir"></td><td class="paramname">allocator</td><td>Allocator object. </td></tr>
<tr><td class="paramdir"></td><td class="paramname">pVkMemoryRequirements</td><td>Memory requirements for each allocation. </td></tr>
<tr><td class="paramdir"></td><td class="paramname">pCreateInfo</td><td>Creation parameters for each alloction. </td></tr>
<tr><td class="paramdir"></td><td class="paramname">allocationCount</td><td>Number of allocations to make. </td></tr>
<tr><td class="paramdir">[out]</td><td class="paramname">pAllocations</td><td>Pointer to array that will be filled with handles to created allocations. </td></tr>
<tr><td class="paramdir">[out]</td><td class="paramname">pAlocationInfo</td><td>Optional. Pointer to array that will be filled with parameters of created allocations.</td></tr>
</table>
</dd>
</dl>
<p>You should free the memory using <a class="el" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568" title="Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). ">vmaFreeMemory()</a> or <a class="el" href="vk__mem__alloc_8h.html#ab9e709de044c5d8476bea77a4e755840" title="Frees memory and destroys multiple allocations. ">vmaFreeMemoryPages()</a>.</p>
<p>Word "pages" is just a suggestion to use this function to allocate pieces of memory needed for sparse binding. It is just a general purpose allocation function able to make multiple allocations at once. It may be internally optimized to be more efficient than calling <a class="el" href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8" title="General purpose memory allocation. ">vmaAllocateMemory()</a> <code>allocationCount</code> times.</p>
<p>All allocations are made using same parameters. All of them are created out of the same memory pool and type. If any allocation fails, all allocations already made within this function call are also freed, so that when returned result is not <code>VK_SUCCESS</code>, <code>pAllocation</code> array is always entirely filled with <code>VK_NULL_HANDLE</code>.</p>
<p>TODO Also write tests for it.</p>
<p>TODO also write test for allocation that will partially fail. </p>
</div>
</div>
<a id="a6b0929b914b60cf2d45cac4bf3547470"></a>
@ -2016,6 +2092,46 @@ Functions</h2></td></tr>
</div><div class="memdoc">
<p>Frees memory previously allocated using <a class="el" href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8" title="General purpose memory allocation. ">vmaAllocateMemory()</a>, <a class="el" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>, or <a class="el" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb" title="Function similar to vmaAllocateMemoryForBuffer(). ">vmaAllocateMemoryForImage()</a>. </p>
<p>Passing <code>VK_NULL_HANDLE</code> as <code>allocation</code> is valid. Such function call is just skipped. </p>
</div>
</div>
<a id="ab9e709de044c5d8476bea77a4e755840"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ab9e709de044c5d8476bea77a4e755840">&#9670;&nbsp;</a></span>vmaFreeMemoryPages()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">void vmaFreeMemoryPages </td>
<td>(</td>
<td class="paramtype"><a class="el" href="struct_vma_allocator.html">VmaAllocator</a>&#160;</td>
<td class="paramname"><em>allocator</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">size_t&#160;</td>
<td class="paramname"><em>allocationCount</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="struct_vma_allocation.html">VmaAllocation</a> *&#160;</td>
<td class="paramname"><em>pAllocations</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Frees memory and destroys multiple allocations. </p>
<p>Word "pages" is just a suggestion to use this function to free pieces of memory used for sparse binding. It is just a general purpose function to free memory and destroy allocations made using e.g. <a class="el" href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8" title="General purpose memory allocation. ">vmaAllocateMemory()</a>, <a class="el" href="vk__mem__alloc_8h.html#ad37e82e492b3de38fc3f4cffd9ad0ae1" title="General purpose memory allocation for multiple allocation objects at once. ">vmaAllocateMemoryPages()</a> and other functions. It may be internally optimized to be more efficient than calling <a class="el" href="vk__mem__alloc_8h.html#a11f0fbc034fa81a4efedd73d61ce7568" title="Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). ">vmaFreeMemory()</a> <code>allocationCount</code> times.</p>
<p>Allocations in <code>pAllocations</code> array can come from any memory pools and types. Passing <code>VK_NULL_HANDLE</code> as elements of <code>pAllocations</code> array is valid. Such entries are just skipped.</p>
<p>TODO Also write tests for it. </p>
</div>
</div>

File diff suppressed because one or more lines are too long

View File

@ -21,7 +21,7 @@ void SaveAllocatorStatsToFile(const wchar_t* filePath);
class BaseImage
{
public:
virtual VkResult Init(RandomNumberGenerator& rand) = 0;
virtual void Init(RandomNumberGenerator& rand) = 0;
virtual ~BaseImage();
protected:
@ -33,7 +33,7 @@ protected:
class TraditionalImage : public BaseImage
{
public:
virtual VkResult Init(RandomNumberGenerator& rand);
virtual void Init(RandomNumberGenerator& rand);
virtual ~TraditionalImage();
private:
@ -43,7 +43,7 @@ private:
class SparseBindingImage : public BaseImage
{
public:
virtual VkResult Init(RandomNumberGenerator& rand);
virtual void Init(RandomNumberGenerator& rand);
virtual ~SparseBindingImage();
private:
@ -73,7 +73,7 @@ void BaseImage::FillImageCreateInfo(VkImageCreateInfo& outInfo, RandomNumberGene
outInfo.extent.height = rand.Generate() % (imageSizeMax - imageSizeMin) + imageSizeMin;
outInfo.extent.depth = 1;
outInfo.mipLevels = 1; // TODO ?
outInfo.arrayLayers = 1; // TODO ?
outInfo.arrayLayers = 1;
outInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
outInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
outInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
@ -85,7 +85,7 @@ void BaseImage::FillImageCreateInfo(VkImageCreateInfo& outInfo, RandomNumberGene
////////////////////////////////////////////////////////////////////////////////
// class TraditionalImage
VkResult TraditionalImage::Init(RandomNumberGenerator& rand)
void TraditionalImage::Init(RandomNumberGenerator& rand)
{
VkImageCreateInfo imageCreateInfo;
FillImageCreateInfo(imageCreateInfo, rand);
@ -95,10 +95,8 @@ VkResult TraditionalImage::Init(RandomNumberGenerator& rand)
// Default BEST_FIT is clearly better.
//allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT;
const VkResult res = vmaCreateImage(g_hAllocator, &imageCreateInfo, &allocCreateInfo,
&m_Image, &m_Allocation, nullptr);
return res;
ERR_GUARD_VULKAN( vmaCreateImage(g_hAllocator, &imageCreateInfo, &allocCreateInfo,
&m_Image, &m_Allocation, nullptr) );
}
TraditionalImage::~TraditionalImage()
@ -112,7 +110,7 @@ TraditionalImage::~TraditionalImage()
////////////////////////////////////////////////////////////////////////////////
// class SparseBindingImage
VkResult SparseBindingImage::Init(RandomNumberGenerator& rand)
void SparseBindingImage::Init(RandomNumberGenerator& rand)
{
assert(g_SparseBindingEnabled && g_hSparseBindingQueue);
@ -120,11 +118,7 @@ VkResult SparseBindingImage::Init(RandomNumberGenerator& rand)
VkImageCreateInfo imageCreateInfo;
FillImageCreateInfo(imageCreateInfo, rand);
imageCreateInfo.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
VkResult res = vkCreateImage(g_hDevice, &imageCreateInfo, nullptr, &m_Image);
if(res != VK_SUCCESS)
{
return res;
}
ERR_GUARD_VULKAN( vkCreateImage(g_hDevice, &imageCreateInfo, nullptr, &m_Image) );
// Get memory requirements.
VkMemoryRequirements imageMemReq;
@ -152,20 +146,16 @@ VkResult SparseBindingImage::Init(RandomNumberGenerator& rand)
m_Allocations.resize(pageCount);
std::fill(m_Allocations.begin(), m_Allocations.end(), nullptr);
std::vector<VkSparseMemoryBind> binds{pageCount};
VmaAllocationInfo allocInfo;
std::vector<VmaAllocationInfo> allocInfo{pageCount};
ERR_GUARD_VULKAN( vmaAllocateMemoryPages(g_hAllocator, &pageMemReq, &allocCreateInfo, pageCount, m_Allocations.data(), allocInfo.data()) );
for(uint32_t i = 0; i < pageCount; ++i)
{
res = vmaAllocateMemory(g_hAllocator, &pageMemReq, &allocCreateInfo, &m_Allocations[i], &allocInfo);
if(res != VK_SUCCESS)
{
return res;
}
binds[i] = {};
binds[i].resourceOffset = pageSize * i;
binds[i].size = pageSize;
binds[i].memory = allocInfo.deviceMemory;
binds[i].memoryOffset = allocInfo.offset;
binds[i].memory = allocInfo[i].deviceMemory;
binds[i].memoryOffset = allocInfo[i].offset;
}
VkSparseImageOpaqueMemoryBindInfo imageBindInfo;
@ -180,16 +170,11 @@ VkResult SparseBindingImage::Init(RandomNumberGenerator& rand)
ERR_GUARD_VULKAN( vkResetFences(g_hDevice, 1, &g_ImmediateFence) );
ERR_GUARD_VULKAN( vkQueueBindSparse(g_hSparseBindingQueue, 1, &bindSparseInfo, g_ImmediateFence) );
ERR_GUARD_VULKAN( vkWaitForFences(g_hDevice, 1, &g_ImmediateFence, VK_TRUE, UINT64_MAX) );
return VK_SUCCESS;
}
SparseBindingImage::~SparseBindingImage()
{
for(size_t i = m_Allocations.size(); i--; )
{
vmaFreeMemory(g_hAllocator, m_Allocations[i]);
}
vmaFreeMemoryPages(g_hAllocator, m_Allocations.size(), m_Allocations.data());
}
////////////////////////////////////////////////////////////////////////////////
@ -223,11 +208,9 @@ void TestSparseBinding()
ImageInfo imageInfo;
//imageInfo.image = std::make_unique<TraditionalImage>();
imageInfo.image = std::make_unique<SparseBindingImage>();
if(imageInfo.image->Init(rand) == VK_SUCCESS)
{
imageInfo.endFrame = g_FrameIndex + rand.Generate() % (imageLifeFramesMax - imageLifeFramesMin) + imageLifeFramesMin;
images.push_back(std::move(imageInfo));
}
imageInfo.image->Init(rand);
imageInfo.endFrame = g_FrameIndex + rand.Generate() % (imageLifeFramesMax - imageLifeFramesMin) + imageLifeFramesMin;
images.push_back(std::move(imageInfo));
// Delete all images that expired.
for(size_t i = images.size(); i--; )

View File

@ -18,8 +18,8 @@ enum CONFIG_TYPE {
CONFIG_TYPE_COUNT
};
//static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_SMALL;
static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_LARGE;
static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_SMALL;
//static constexpr CONFIG_TYPE ConfigType = CONFIG_TYPE_LARGE;
enum class FREE_ORDER { FORWARD, BACKWARD, RANDOM, COUNT };

View File

@ -2319,7 +2319,7 @@ typedef struct VmaAllocationInfo {
@param[out] pAllocation Handle to allocated memory.
@param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo().
You should free the memory using vmaFreeMemory().
You should free the memory using vmaFreeMemory() or vmaFreeMemoryPages().
It is recommended to use vmaAllocateMemoryForBuffer(), vmaAllocateMemoryForImage(),
vmaCreateBuffer(), vmaCreateImage() instead whenever possible.
@ -2331,6 +2331,33 @@ VkResult vmaAllocateMemory(
VmaAllocation* pAllocation,
VmaAllocationInfo* pAllocationInfo);
/** \brief General purpose memory allocation for multiple allocation objects at once.
@param allocator Allocator object.
@param pVkMemoryRequirements Memory requirements for each allocation.
@param pCreateInfo Creation parameters for each alloction.
@param allocationCount Number of allocations to make.
@param[out] pAllocations Pointer to array that will be filled with handles to created allocations.
@param[out] pAlocationInfo Optional. Pointer to array that will be filled with parameters of created allocations.
You should free the memory using vmaFreeMemory() or vmaFreeMemoryPages().
Word "pages" is just a suggestion to use this function to allocate pieces of memory needed for sparse binding.
It is just a general purpose allocation function able to make multiple allocations at once.
It may be internally optimized to be more efficient than calling vmaAllocateMemory() `allocationCount` times.
All allocations are made using same parameters. All of them are created out of the same memory pool and type.
If any allocation fails, all allocations already made within this function call are also freed, so that when
returned result is not `VK_SUCCESS`, `pAllocation` array is always entirely filled with `VK_NULL_HANDLE`.
*/
VkResult vmaAllocateMemoryPages(
VmaAllocator allocator,
const VkMemoryRequirements* pVkMemoryRequirements,
const VmaAllocationCreateInfo* pCreateInfo,
size_t allocationCount,
VmaAllocation* pAllocations,
VmaAllocationInfo* pAllocationInfo);
/**
@param[out] pAllocation Handle to allocated memory.
@param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo().
@ -2352,11 +2379,29 @@ VkResult vmaAllocateMemoryForImage(
VmaAllocation* pAllocation,
VmaAllocationInfo* pAllocationInfo);
/// Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage().
/** \brief Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage().
Passing `VK_NULL_HANDLE` as `allocation` is valid. Such function call is just skipped.
*/
void vmaFreeMemory(
VmaAllocator allocator,
VmaAllocation allocation);
/** \brief Frees memory and destroys multiple allocations.
Word "pages" is just a suggestion to use this function to free pieces of memory used for sparse binding.
It is just a general purpose function to free memory and destroy allocations made using e.g. vmaAllocateMemory(),
vmaAllocateMemoryPages() and other functions.
It may be internally optimized to be more efficient than calling vmaFreeMemory() `allocationCount` times.
Allocations in `pAllocations` array can come from any memory pools and types.
Passing `VK_NULL_HANDLE` as elements of `pAllocations` array is valid. Such entries are just skipped.
*/
void vmaFreeMemoryPages(
VmaAllocator allocator,
size_t allocationCount,
VmaAllocation* pAllocations);
/** \brief Returns current information about specified allocation and atomically marks it as used in current frame.
Current paramters of given allocation are returned in `pAllocationInfo`.
@ -5302,7 +5347,8 @@ public:
VkDeviceSize alignment,
const VmaAllocationCreateInfo& createInfo,
VmaSuballocationType suballocType,
VmaAllocation* pAllocation);
size_t allocationCount,
VmaAllocation* pAllocations);
void Free(
VmaAllocation hAllocation);
@ -5362,6 +5408,15 @@ private:
// after this call.
void IncrementallySortBlocks();
VkResult AllocatePage(
VmaPool hCurrentPool,
uint32_t currentFrameIndex,
VkDeviceSize size,
VkDeviceSize alignment,
const VmaAllocationCreateInfo& createInfo,
VmaSuballocationType suballocType,
VmaAllocation* pAllocation);
// To be used only without CAN_MAKE_OTHER_LOST flag.
VkResult AllocateFromBlock(
VmaDeviceMemoryBlock* pBlock,
@ -5729,10 +5784,13 @@ public:
VkImage dedicatedImage,
const VmaAllocationCreateInfo& createInfo,
VmaSuballocationType suballocType,
VmaAllocation* pAllocation);
size_t allocationCount,
VmaAllocation* pAllocations);
// Main deallocation function.
void FreeMemory(const VmaAllocation allocation);
void FreeMemory(
size_t allocationCount,
const VmaAllocation* pAllocations);
void CalculateStats(VmaStats* pStats);
@ -5811,9 +5869,21 @@ private:
const VmaAllocationCreateInfo& createInfo,
uint32_t memTypeIndex,
VmaSuballocationType suballocType,
size_t allocationCount,
VmaAllocation* pAllocations);
// Helper function only to be used inside AllocateDedicatedMemory.
VkResult AllocateDedicatedMemoryPage(
VkDeviceSize size,
VmaSuballocationType suballocType,
uint32_t memTypeIndex,
const VkMemoryAllocateInfo& allocInfo,
bool map,
bool isUserDataString,
void* pUserData,
VmaAllocation* pAllocation);
// Allocates and registers new VkDeviceMemory specifically for single allocation.
// Allocates and registers new VkDeviceMemory specifically for dedicated allocations.
VkResult AllocateDedicatedMemory(
VkDeviceSize size,
VmaSuballocationType suballocType,
@ -5823,7 +5893,8 @@ private:
void* pUserData,
VkBuffer dedicatedBuffer,
VkImage dedicatedImage,
VmaAllocation* pAllocation);
size_t allocationCount,
VmaAllocation* pAllocations);
// Tries to free pMemory as Dedicated Memory. Returns true if found and freed.
void FreeDedicatedMemory(VmaAllocation allocation);
@ -10213,6 +10284,51 @@ bool VmaBlockVector::IsCorruptionDetectionEnabled() const
static const uint32_t VMA_ALLOCATION_TRY_COUNT = 32;
VkResult VmaBlockVector::Allocate(
VmaPool hCurrentPool,
uint32_t currentFrameIndex,
VkDeviceSize size,
VkDeviceSize alignment,
const VmaAllocationCreateInfo& createInfo,
VmaSuballocationType suballocType,
size_t allocationCount,
VmaAllocation* pAllocations)
{
size_t allocIndex;
VkResult res = VK_SUCCESS;
{
VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex);
for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex)
{
res = AllocatePage(
hCurrentPool,
currentFrameIndex,
size,
alignment,
createInfo,
suballocType,
pAllocations + allocIndex);
if(res != VK_SUCCESS)
{
break;
}
}
}
if(res != VK_SUCCESS)
{
// Free all already created allocations.
while(allocIndex--)
{
Free(pAllocations[allocIndex]);
}
memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount);
}
return res;
}
VkResult VmaBlockVector::AllocatePage(
VmaPool hCurrentPool,
uint32_t currentFrameIndex,
VkDeviceSize size,
@ -10264,8 +10380,6 @@ VkResult VmaBlockVector::Allocate(
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}
VmaMutexLock lock(m_Mutex, m_hAllocator->m_UseMutex);
/*
Under certain condition, this whole section can be skipped for optimization, so
we move on directly to trying to allocate with canMakeOtherLost. That's the case
@ -12035,10 +12149,11 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
const VmaAllocationCreateInfo& createInfo,
uint32_t memTypeIndex,
VmaSuballocationType suballocType,
VmaAllocation* pAllocation)
size_t allocationCount,
VmaAllocation* pAllocations)
{
VMA_ASSERT(pAllocation != VMA_NULL);
VMA_DEBUG_LOG(" AllocateMemory: MemoryTypeIndex=%u, Size=%llu", memTypeIndex, vkMemReq.size);
VMA_ASSERT(pAllocations != VMA_NULL);
VMA_DEBUG_LOG(" AllocateMemory: MemoryTypeIndex=%u, AllocationCount=%zu, Size=%llu", memTypeIndex, allocationCount, vkMemReq.size);
VmaAllocationCreateInfo finalCreateInfo = createInfo;
@ -12083,7 +12198,8 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
finalCreateInfo.pUserData,
dedicatedBuffer,
dedicatedImage,
pAllocation);
allocationCount,
pAllocations);
}
}
else
@ -12095,7 +12211,8 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
alignment,
finalCreateInfo,
suballocType,
pAllocation);
allocationCount,
pAllocations);
if(res == VK_SUCCESS)
{
return res;
@ -12117,7 +12234,8 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
finalCreateInfo.pUserData,
dedicatedBuffer,
dedicatedImage,
pAllocation);
allocationCount,
pAllocations);
if(res == VK_SUCCESS)
{
// Succeeded: AllocateDedicatedMemory function already filld pMemory, nothing more to do here.
@ -12143,9 +12261,10 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory(
void* pUserData,
VkBuffer dedicatedBuffer,
VkImage dedicatedImage,
VmaAllocation* pAllocation)
size_t allocationCount,
VmaAllocation* pAllocations)
{
VMA_ASSERT(pAllocation);
VMA_ASSERT(allocationCount > 0 && pAllocations);
VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
allocInfo.memoryTypeIndex = memTypeIndex;
@ -12169,7 +12288,80 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory(
}
#endif // #if VMA_DEDICATED_ALLOCATION
// Allocate VkDeviceMemory.
size_t allocIndex;
VkResult res;
for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex)
{
res = AllocateDedicatedMemoryPage(
size,
suballocType,
memTypeIndex,
allocInfo,
map,
isUserDataString,
pUserData,
pAllocations + allocIndex);
if(res != VK_SUCCESS)
{
break;
}
}
if(res == VK_SUCCESS)
{
// Register them in m_pDedicatedAllocations.
{
VmaMutexLock lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);
AllocationVectorType* pDedicatedAllocations = m_pDedicatedAllocations[memTypeIndex];
VMA_ASSERT(pDedicatedAllocations);
for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex)
{
VmaVectorInsertSorted<VmaPointerLess>(*pDedicatedAllocations, pAllocations[allocIndex]);
}
}
VMA_DEBUG_LOG(" Allocated DedicatedMemory Count=%zu, MemoryTypeIndex=#%u", allocationCount, memTypeIndex);
}
else
{
// Free all already created allocations.
while(allocIndex--)
{
VmaAllocation currAlloc = pAllocations[allocIndex];
VkDeviceMemory hMemory = currAlloc->GetMemory();
/*
There is no need to call this, because Vulkan spec allows to skip vkUnmapMemory
before vkFreeMemory.
if(currAlloc->GetMappedData() != VMA_NULL)
{
(*m_VulkanFunctions.vkUnmapMemory)(m_hDevice, hMemory);
}
*/
FreeVulkanMemory(memTypeIndex, currAlloc->GetSize(), hMemory);
currAlloc->SetUserData(this, VMA_NULL);
vma_delete(this, currAlloc);
}
memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount);
}
return res;
}
VkResult VmaAllocator_T::AllocateDedicatedMemoryPage(
VkDeviceSize size,
VmaSuballocationType suballocType,
uint32_t memTypeIndex,
const VkMemoryAllocateInfo& allocInfo,
bool map,
bool isUserDataString,
void* pUserData,
VmaAllocation* pAllocation)
{
VkDeviceMemory hMemory = VK_NULL_HANDLE;
VkResult res = AllocateVulkanMemory(&allocInfo, &hMemory);
if(res < 0)
@ -12204,16 +12396,6 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory(
FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);
}
// Register it in m_pDedicatedAllocations.
{
VmaMutexLock lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);
AllocationVectorType* pDedicatedAllocations = m_pDedicatedAllocations[memTypeIndex];
VMA_ASSERT(pDedicatedAllocations);
VmaVectorInsertSorted<VmaPointerLess>(*pDedicatedAllocations, *pAllocation);
}
VMA_DEBUG_LOG(" Allocated DedicatedMemory MemoryTypeIndex=#%u", memTypeIndex);
return VK_SUCCESS;
}
@ -12289,8 +12471,11 @@ VkResult VmaAllocator_T::AllocateMemory(
VkImage dedicatedImage,
const VmaAllocationCreateInfo& createInfo,
VmaSuballocationType suballocType,
VmaAllocation* pAllocation)
size_t allocationCount,
VmaAllocation* pAllocations)
{
memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount);
VMA_ASSERT(VmaIsPow2(vkMemReq.alignment));
if((createInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0 &&
@ -12337,7 +12522,8 @@ VkResult VmaAllocator_T::AllocateMemory(
alignmentForPool,
createInfo,
suballocType,
pAllocation);
allocationCount,
pAllocations);
}
else
{
@ -12360,7 +12546,8 @@ VkResult VmaAllocator_T::AllocateMemory(
createInfo,
memTypeIndex,
suballocType,
pAllocation);
allocationCount,
pAllocations);
// Succeeded on first try.
if(res == VK_SUCCESS)
{
@ -12390,7 +12577,8 @@ VkResult VmaAllocator_T::AllocateMemory(
createInfo,
memTypeIndex,
suballocType,
pAllocation);
allocationCount,
pAllocations);
// Allocation from this alternative memory type succeeded.
if(res == VK_SUCCESS)
{
@ -12413,45 +12601,55 @@ VkResult VmaAllocator_T::AllocateMemory(
}
}
void VmaAllocator_T::FreeMemory(const VmaAllocation allocation)
void VmaAllocator_T::FreeMemory(
size_t allocationCount,
const VmaAllocation* pAllocations)
{
VMA_ASSERT(allocation);
VMA_ASSERT(pAllocations);
if(TouchAllocation(allocation))
for(size_t allocIndex = allocationCount; allocIndex--; )
{
if(VMA_DEBUG_INITIALIZE_ALLOCATIONS)
{
FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);
}
VmaAllocation allocation = pAllocations[allocIndex];
switch(allocation->GetType())
if(allocation != VK_NULL_HANDLE)
{
case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
if(TouchAllocation(allocation))
{
VmaBlockVector* pBlockVector = VMA_NULL;
VmaPool hPool = allocation->GetPool();
if(hPool != VK_NULL_HANDLE)
if(VMA_DEBUG_INITIALIZE_ALLOCATIONS)
{
pBlockVector = &hPool->m_BlockVector;
FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);
}
else
switch(allocation->GetType())
{
const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
pBlockVector = m_pBlockVectors[memTypeIndex];
case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
{
VmaBlockVector* pBlockVector = VMA_NULL;
VmaPool hPool = allocation->GetPool();
if(hPool != VK_NULL_HANDLE)
{
pBlockVector = &hPool->m_BlockVector;
}
else
{
const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
pBlockVector = m_pBlockVectors[memTypeIndex];
}
pBlockVector->Free(allocation);
}
break;
case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
FreeDedicatedMemory(allocation);
break;
default:
VMA_ASSERT(0);
}
pBlockVector->Free(allocation);
}
break;
case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
FreeDedicatedMemory(allocation);
break;
default:
VMA_ASSERT(0);
allocation->SetUserData(this, VMA_NULL);
vma_delete(this, allocation);
}
}
allocation->SetUserData(this, VMA_NULL);
vma_delete(this, allocation);
}
void VmaAllocator_T::CalculateStats(VmaStats* pStats)
@ -13707,6 +13905,7 @@ VkResult vmaAllocateMemory(
VK_NULL_HANDLE, // dedicatedImage
*pCreateInfo,
VMA_SUBALLOCATION_TYPE_UNKNOWN,
1, // allocationCount
pAllocation);
#if VMA_RECORDING_ENABLED
@ -13728,6 +13927,61 @@ VkResult vmaAllocateMemory(
return result;
}
VkResult vmaAllocateMemoryPages(
VmaAllocator allocator,
const VkMemoryRequirements* pVkMemoryRequirements,
const VmaAllocationCreateInfo* pCreateInfo,
size_t allocationCount,
VmaAllocation* pAllocations,
VmaAllocationInfo* pAllocationInfo)
{
if(allocationCount == 0)
{
return VK_SUCCESS;
}
VMA_ASSERT(allocator && pVkMemoryRequirements && pCreateInfo && pAllocations);
VMA_DEBUG_LOG("vmaAllocateMemoryPages");
VMA_DEBUG_GLOBAL_MUTEX_LOCK
VkResult result = allocator->AllocateMemory(
*pVkMemoryRequirements,
false, // requiresDedicatedAllocation
false, // prefersDedicatedAllocation
VK_NULL_HANDLE, // dedicatedBuffer
VK_NULL_HANDLE, // dedicatedImage
*pCreateInfo,
VMA_SUBALLOCATION_TYPE_UNKNOWN,
allocationCount,
pAllocations);
#if VMA_RECORDING_ENABLED
if(allocator->GetRecorder() != VMA_NULL)
{
// TODO: Extend recording format with this function.
/*
allocator->GetRecorder()->RecordAllocateMemoryPages(
allocator->GetCurrentFrameIndex(),
*pVkMemoryRequirements,
*pCreateInfo,
*pAllocation);
*/
}
#endif
if(pAllocationInfo != VMA_NULL && result == VK_SUCCESS)
{
for(size_t i = 0; i < allocationCount; ++i)
{
allocator->GetAllocationInfo(pAllocations[i], pAllocationInfo + i);
}
}
return result;
}
VkResult vmaAllocateMemoryForBuffer(
VmaAllocator allocator,
VkBuffer buffer,
@ -13756,6 +14010,7 @@ VkResult vmaAllocateMemoryForBuffer(
VK_NULL_HANDLE, // dedicatedImage
*pCreateInfo,
VMA_SUBALLOCATION_TYPE_BUFFER,
1, // allocationCount
pAllocation);
#if VMA_RECORDING_ENABLED
@ -13806,6 +14061,7 @@ VkResult vmaAllocateMemoryForImage(
image, // dedicatedImage
*pCreateInfo,
VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN,
1, // allocationCount
pAllocation);
#if VMA_RECORDING_ENABLED
@ -13853,7 +14109,40 @@ void vmaFreeMemory(
}
#endif
allocator->FreeMemory(allocation);
allocator->FreeMemory(
1, // allocationCount
&allocation);
}
void vmaFreeMemoryPages(
VmaAllocator allocator,
size_t allocationCount,
VmaAllocation* pAllocations)
{
if(allocationCount == 0)
{
return;
}
VMA_ASSERT(allocator);
VMA_DEBUG_LOG("vmaFreeMemoryPages");
VMA_DEBUG_GLOBAL_MUTEX_LOCK
#if VMA_RECORDING_ENABLED
// TODO Add this to recording file format.
/*
if(allocator->GetRecorder() != VMA_NULL)
{
allocator->GetRecorder()->RecordFreeMemoryPages(
allocator->GetCurrentFrameIndex(),
allocation);
}
*/
#endif
allocator->FreeMemory(allocationCount, pAllocations);
}
void vmaGetAllocationInfo(
@ -14137,6 +14426,7 @@ VkResult vmaCreateBuffer(
VK_NULL_HANDLE, // dedicatedImage
*pAllocationCreateInfo,
VMA_SUBALLOCATION_TYPE_BUFFER,
1, // allocationCount
pAllocation);
#if VMA_RECORDING_ENABLED
@ -14167,7 +14457,9 @@ VkResult vmaCreateBuffer(
return VK_SUCCESS;
}
allocator->FreeMemory(*pAllocation);
allocator->FreeMemory(
1, // allocationCount
pAllocation);
*pAllocation = VK_NULL_HANDLE;
(*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());
*pBuffer = VK_NULL_HANDLE;
@ -14212,7 +14504,9 @@ void vmaDestroyBuffer(
if(allocation != VK_NULL_HANDLE)
{
allocator->FreeMemory(allocation);
allocator->FreeMemory(
1, // allocationCount
&allocation);
}
}
@ -14260,6 +14554,7 @@ VkResult vmaCreateImage(
*pImage, // dedicatedImage
*pAllocationCreateInfo,
suballocType,
1, // allocationCount
pAllocation);
#if VMA_RECORDING_ENABLED
@ -14290,7 +14585,9 @@ VkResult vmaCreateImage(
return VK_SUCCESS;
}
allocator->FreeMemory(*pAllocation);
allocator->FreeMemory(
1, // allocationCount
pAllocation);
*pAllocation = VK_NULL_HANDLE;
(*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, *pImage, allocator->GetAllocationCallbacks());
*pImage = VK_NULL_HANDLE;
@ -14334,7 +14631,9 @@ void vmaDestroyImage(
}
if(allocation != VK_NULL_HANDLE)
{
allocator->FreeMemory(allocation);
allocator->FreeMemory(
1, // allocationCount
&allocation);
}
}