mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
synced 2024-11-21 20:00:11 +00:00
Added feature: VmaAllocatorCreateInfo::pHeapSizeLimit.
This commit is contained in:
parent
a89a26c452
commit
118049cda8
Binary file not shown.
@ -170,6 +170,9 @@ $(function() {
|
||||
<li>pfnFree
|
||||
: <a class="el" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">VmaDeviceMemoryCallbacks</a>
|
||||
</li>
|
||||
<li>pHeapSizeLimit
|
||||
: <a class="el" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">VmaAllocatorCreateInfo</a>
|
||||
</li>
|
||||
<li>physicalDevice
|
||||
: <a class="el" href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156">VmaAllocatorCreateInfo</a>
|
||||
</li>
|
||||
|
@ -170,6 +170,9 @@ $(function() {
|
||||
<li>pfnFree
|
||||
: <a class="el" href="struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c">VmaDeviceMemoryCallbacks</a>
|
||||
</li>
|
||||
<li>pHeapSizeLimit
|
||||
: <a class="el" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">VmaAllocatorCreateInfo</a>
|
||||
</li>
|
||||
<li>physicalDevice
|
||||
: <a class="el" href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156">VmaAllocatorCreateInfo</a>
|
||||
</li>
|
||||
|
@ -73,7 +73,9 @@ $(function() {
|
||||
<li class="level2"><a href="#lost_allocations">Lost allocations</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="level1"><a href="#configuration">Configuration</a><ul><li class="level2"><a href="#custom_memory_allocator">Custom memory allocator</a></li>
|
||||
<li class="level1"><a href="#configuration">Configuration</a><ul><li class="level2"><a href="#custom_memory_allocator">Custom host memory allocator</a></li>
|
||||
<li class="level2"><a href="#allocation_callbacks">Device memory allocation callbacks</a></li>
|
||||
<li class="level2"><a href="#heap_memory_limit">Device heap memory limit</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="level1"><a href="#thread_safety">Thread safety</a></li>
|
||||
@ -295,10 +297,16 @@ void MyBuffer::EnsureBuffer()
|
||||
</ol>
|
||||
<h1><a class="anchor" id="configuration"></a>
|
||||
Configuration</h1>
|
||||
<p>Please check "CONFIGURATION SECTION" in the code to find macros that you can define before each <code>#include</code> of this file or change directly in this file to provide your own implementation of basic facilities like assert, min and max functions, mutex etc. C++ STL is used by default, but changing these allows you to get rid of any STL usage if you want, as many game developers tend to do.</p>
|
||||
<p>Please check "CONFIGURATION SECTION" in the code to find macros that you can define before each <code>#include</code> of this file or change directly in this file to provide your own implementation of basic facilities like assert, <code>min()</code> and <code>max()</code> functions, mutex etc. C++ STL is used by default, but changing these allows you to get rid of any STL usage if you want, as many game developers tend to do.</p>
|
||||
<h2><a class="anchor" id="custom_memory_allocator"></a>
|
||||
Custom memory allocator</h2>
|
||||
<p>You can use custom memory allocator by filling optional member <a class="el" href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d" title="Custom CPU memory allocation callbacks. ">VmaAllocatorCreateInfo::pAllocationCallbacks</a>. These functions will be passed to Vulkan, as well as used by the library itself to make any CPU-side allocations.</p>
|
||||
Custom host memory allocator</h2>
|
||||
<p>If you use custom allocator for CPU memory rather than default operator <code>new</code> and <code>delete</code> from C++, you can make this library using your allocator as well by filling optional member <a class="el" href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d" title="Custom CPU memory allocation callbacks. ">VmaAllocatorCreateInfo::pAllocationCallbacks</a>. These functions will be passed to Vulkan, as well as used by the library itself to make any CPU-side allocations.</p>
|
||||
<h2><a class="anchor" id="allocation_callbacks"></a>
|
||||
Device memory allocation callbacks</h2>
|
||||
<p>The library makes calls to <code>vkAllocateMemory()</code> and <code>vkFreeMemory()</code> internally. You can setup callbacks to be informed about these calls, e.g. for the purpose of gathering some statistics. To do it, fill optional member <a class="el" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e" title="Informative callbacks for vkAllocateMemory, vkFreeMemory. ">VmaAllocatorCreateInfo::pDeviceMemoryCallbacks</a>.</p>
|
||||
<h2><a class="anchor" id="heap_memory_limit"></a>
|
||||
Device heap memory limit</h2>
|
||||
<p>If you want to test how your program behaves with limited amount of Vulkan device memory available (without switching your graphics card to one that really has smaller VRAM), you can use a feature of this library intended for this purpose. To do it, fill optional member <a class="el" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b" title="Either NULL or a pointer to an array of limits on maximum number of bytes that can be allocated out o...">VmaAllocatorCreateInfo::pHeapSizeLimit</a>.</p>
|
||||
<h1><a class="anchor" id="thread_safety"></a>
|
||||
Thread safety</h1>
|
||||
<ul>
|
||||
|
@ -6,6 +6,7 @@ var searchData=
|
||||
['pfn_5fvmafreedevicememoryfunction',['PFN_vmaFreeDeviceMemoryFunction',['../group__general.html#gaef2545dc2e9dd4f29ab9ba6ac6fe2f49',1,'vk_mem_alloc.h']]],
|
||||
['pfnallocate',['pfnAllocate',['../struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb',1,'VmaDeviceMemoryCallbacks']]],
|
||||
['pfnfree',['pfnFree',['../struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c',1,'VmaDeviceMemoryCallbacks']]],
|
||||
['pheapsizelimit',['pHeapSizeLimit',['../struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b',1,'VmaAllocatorCreateInfo']]],
|
||||
['physicaldevice',['physicalDevice',['../struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156',1,'VmaAllocatorCreateInfo']]],
|
||||
['pmappeddata',['pMappedData',['../struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2',1,'VmaAllocationInfo']]],
|
||||
['pool',['pool',['../struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150',1,'VmaAllocationCreateInfo']]],
|
||||
|
@ -1,7 +1,7 @@
|
||||
var searchData=
|
||||
[
|
||||
['unusedbytes',['UnusedBytes',['../struct_vma_stat_info.html#a394d2aef4348cb58abf73764804b4f2d',1,'VmaStatInfo']]],
|
||||
['unusedrangecount',['UnusedRangeCount',['../struct_vma_stat_info.html#a56c4fb4dba646479180b601854cde2a6',1,'VmaStatInfo::UnusedRangeCount()'],['../struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4',1,'VmaPoolStats::unusedRangeCount()']]],
|
||||
['unusedrangecount',['unusedRangeCount',['../struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4',1,'VmaPoolStats::unusedRangeCount()'],['../struct_vma_stat_info.html#a56c4fb4dba646479180b601854cde2a6',1,'VmaStatInfo::UnusedRangeCount()']]],
|
||||
['unusedrangesizeavg',['UnusedRangeSizeAvg',['../struct_vma_stat_info.html#a88ad9bdc2b3a98964a4d0c338c0c9060',1,'VmaStatInfo']]],
|
||||
['unusedrangesizemax',['UnusedRangeSizeMax',['../struct_vma_stat_info.html#a10c52c0841f01ca704e8ddb1ea6a635d',1,'VmaStatInfo']]],
|
||||
['unusedrangesizemin',['UnusedRangeSizeMin',['../struct_vma_stat_info.html#a07c508f42a4d3424bd0c259784a7f2d6',1,'VmaStatInfo']]],
|
||||
|
@ -4,6 +4,7 @@ var searchData=
|
||||
['pdevicememorycallbacks',['pDeviceMemoryCallbacks',['../struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e',1,'VmaAllocatorCreateInfo']]],
|
||||
['pfnallocate',['pfnAllocate',['../struct_vma_device_memory_callbacks.html#a4f17f7b255101e733b44d5633aceabfb',1,'VmaDeviceMemoryCallbacks']]],
|
||||
['pfnfree',['pfnFree',['../struct_vma_device_memory_callbacks.html#abe8a3328bbc916f6f712fdb6b299444c',1,'VmaDeviceMemoryCallbacks']]],
|
||||
['pheapsizelimit',['pHeapSizeLimit',['../struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b',1,'VmaAllocatorCreateInfo']]],
|
||||
['physicaldevice',['physicalDevice',['../struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156',1,'VmaAllocatorCreateInfo']]],
|
||||
['pmappeddata',['pMappedData',['../struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2',1,'VmaAllocationInfo']]],
|
||||
['pool',['pool',['../struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150',1,'VmaAllocationCreateInfo']]],
|
||||
|
@ -1,7 +1,7 @@
|
||||
var searchData=
|
||||
[
|
||||
['unusedbytes',['UnusedBytes',['../struct_vma_stat_info.html#a394d2aef4348cb58abf73764804b4f2d',1,'VmaStatInfo']]],
|
||||
['unusedrangecount',['UnusedRangeCount',['../struct_vma_stat_info.html#a56c4fb4dba646479180b601854cde2a6',1,'VmaStatInfo::UnusedRangeCount()'],['../struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4',1,'VmaPoolStats::unusedRangeCount()']]],
|
||||
['unusedrangecount',['unusedRangeCount',['../struct_vma_pool_stats.html#ae4f3546ffa4d1e598b64d8e6134854f4',1,'VmaPoolStats::unusedRangeCount()'],['../struct_vma_stat_info.html#a56c4fb4dba646479180b601854cde2a6',1,'VmaStatInfo::UnusedRangeCount()']]],
|
||||
['unusedrangesizeavg',['UnusedRangeSizeAvg',['../struct_vma_stat_info.html#a88ad9bdc2b3a98964a4d0c338c0c9060',1,'VmaStatInfo']]],
|
||||
['unusedrangesizemax',['UnusedRangeSizeMax',['../struct_vma_stat_info.html#a10c52c0841f01ca704e8ddb1ea6a635d',1,'VmaStatInfo']]],
|
||||
['unusedrangesizemin',['UnusedRangeSizeMin',['../struct_vma_stat_info.html#a07c508f42a4d3424bd0c259784a7f2d6',1,'VmaStatInfo']]],
|
||||
|
@ -70,9 +70,10 @@ $(function() {
|
||||
<tr class="even"><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7">frameInUseCount</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d">pAllocationCallbacks</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">pDeviceMemoryCallbacks</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156">physicalDevice</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#ab435423d84d5ab26e2c347c51771f90a">preferredSmallHeapBlockSize</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">pHeapSizeLimit</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a08230f04ae6ccf8a78150a9e829a7156">physicalDevice</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html#ab435423d84d5ab26e2c347c51771f90a">preferredSmallHeapBlockSize</a></td><td class="entry"><a class="el" href="struct_vma_allocator_create_info.html">VmaAllocatorCreateInfo</a></td><td class="entry"></td></tr>
|
||||
</table></div><!-- contents -->
|
||||
<!-- start footer part -->
|
||||
<hr class="footer"/><address class="footer"><small>
|
||||
|
@ -83,10 +83,10 @@ Public Attributes</h2></td></tr>
|
||||
<tr class="memdesc:ad924ddd77b04039c88d0c09b0ffcd500"><td class="mdescLeft"> </td><td class="mdescRight">Vulkan device. <a href="#ad924ddd77b04039c88d0c09b0ffcd500">More...</a><br /></td></tr>
|
||||
<tr class="separator:ad924ddd77b04039c88d0c09b0ffcd500"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:a8e4714298e3121cdd8b214a1ae7a637a"><td class="memItemLeft" align="right" valign="top">VkDeviceSize </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html#a8e4714298e3121cdd8b214a1ae7a637a">preferredLargeHeapBlockSize</a></td></tr>
|
||||
<tr class="memdesc:a8e4714298e3121cdd8b214a1ae7a637a"><td class="mdescLeft"> </td><td class="mdescRight">Size of a single memory block to allocate for resources. <a href="#a8e4714298e3121cdd8b214a1ae7a637a">More...</a><br /></td></tr>
|
||||
<tr class="memdesc:a8e4714298e3121cdd8b214a1ae7a637a"><td class="mdescLeft"> </td><td class="mdescRight">Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from large heaps. <a href="#a8e4714298e3121cdd8b214a1ae7a637a">More...</a><br /></td></tr>
|
||||
<tr class="separator:a8e4714298e3121cdd8b214a1ae7a637a"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:ab435423d84d5ab26e2c347c51771f90a"><td class="memItemLeft" align="right" valign="top">VkDeviceSize </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html#ab435423d84d5ab26e2c347c51771f90a">preferredSmallHeapBlockSize</a></td></tr>
|
||||
<tr class="memdesc:ab435423d84d5ab26e2c347c51771f90a"><td class="mdescLeft"> </td><td class="mdescRight">Size of a single memory block to allocate for resources from a small heap <= 512 MB. <a href="#ab435423d84d5ab26e2c347c51771f90a">More...</a><br /></td></tr>
|
||||
<tr class="memdesc:ab435423d84d5ab26e2c347c51771f90a"><td class="mdescLeft"> </td><td class="mdescRight">Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from small heaps <= 512 MB. <a href="#ab435423d84d5ab26e2c347c51771f90a">More...</a><br /></td></tr>
|
||||
<tr class="separator:ab435423d84d5ab26e2c347c51771f90a"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:a6e409087e3be55400d0e4ccbe43c608d"><td class="memItemLeft" align="right" valign="top">const VkAllocationCallbacks * </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html#a6e409087e3be55400d0e4ccbe43c608d">pAllocationCallbacks</a></td></tr>
|
||||
<tr class="memdesc:a6e409087e3be55400d0e4ccbe43c608d"><td class="mdescLeft"> </td><td class="mdescRight">Custom CPU memory allocation callbacks. <a href="#a6e409087e3be55400d0e4ccbe43c608d">More...</a><br /></td></tr>
|
||||
@ -97,6 +97,9 @@ Public Attributes</h2></td></tr>
|
||||
<tr class="memitem:a21ea188dd212b8171cb9ecbed4a2a3a7"><td class="memItemLeft" align="right" valign="top">uint32_t </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7">frameInUseCount</a></td></tr>
|
||||
<tr class="memdesc:a21ea188dd212b8171cb9ecbed4a2a3a7"><td class="mdescLeft"> </td><td class="mdescRight">Maximum number of additional frames that are in use at the same time as current frame. <a href="#a21ea188dd212b8171cb9ecbed4a2a3a7">More...</a><br /></td></tr>
|
||||
<tr class="separator:a21ea188dd212b8171cb9ecbed4a2a3a7"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:a31c192aa6cbffa33279f6d9f0c47c44b"><td class="memItemLeft" align="right" valign="top">const VkDeviceSize * </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html#a31c192aa6cbffa33279f6d9f0c47c44b">pHeapSizeLimit</a></td></tr>
|
||||
<tr class="memdesc:a31c192aa6cbffa33279f6d9f0c47c44b"><td class="mdescLeft"> </td><td class="mdescRight">Either NULL or a pointer to an array of limits on maximum number of bytes that can be allocated out of particular Vulkan memory heap. <a href="#a31c192aa6cbffa33279f6d9f0c47c44b">More...</a><br /></td></tr>
|
||||
<tr class="separator:a31c192aa6cbffa33279f6d9f0c47c44b"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
</table>
|
||||
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
|
||||
<div class="textblock"><p>Description of a Allocator to be created. </p>
|
||||
@ -185,6 +188,29 @@ Public Attributes</h2></td></tr>
|
||||
<p>Informative callbacks for vkAllocateMemory, vkFreeMemory. </p>
|
||||
<p>Optional, can be null. </p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<a id="a31c192aa6cbffa33279f6d9f0c47c44b"></a>
|
||||
<h2 class="memtitle"><span class="permalink"><a href="#a31c192aa6cbffa33279f6d9f0c47c44b">◆ </a></span>pHeapSizeLimit</h2>
|
||||
|
||||
<div class="memitem">
|
||||
<div class="memproto">
|
||||
<table class="memname">
|
||||
<tr>
|
||||
<td class="memname">const VkDeviceSize* VmaAllocatorCreateInfo::pHeapSizeLimit</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div><div class="memdoc">
|
||||
|
||||
<p>Either NULL or a pointer to an array of limits on maximum number of bytes that can be allocated out of particular Vulkan memory heap. </p>
|
||||
<p>If not NULL, it must be a pointer to an array of <code>VkPhysicalDeviceMemoryProperties::memoryHeapCount</code> elements, defining limit on maximum number of bytes that can be allocated out of particular Vulkan memory heap.</p>
|
||||
<p>Any of the elements may be equal to <code>VK_WHOLE_SIZE</code>, which means no limit on that heap. This is also the default in case of <code>pHeapSizeLimit</code> = NULL.</p>
|
||||
<p>If there is a limit defined for a heap:</p>
|
||||
<ul>
|
||||
<li>If user tries to allocate more memory from that heap using this allocator, the allocation fails with <code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code>.</li>
|
||||
<li>If the limit is smaller than heap size reported in <code>VkMemoryHeap::size</code>, the value of this limit will be reported instead when using <a class="el" href="group__general.html#gab88db292a17974f911182543fda52d19">vmaGetMemoryProperties()</a>. </li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<a id="a08230f04ae6ccf8a78150a9e829a7156"></a>
|
||||
@ -216,7 +242,7 @@ Public Attributes</h2></td></tr>
|
||||
</table>
|
||||
</div><div class="memdoc">
|
||||
|
||||
<p>Size of a single memory block to allocate for resources. </p>
|
||||
<p>Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from large heaps. </p>
|
||||
<p>Set to 0 to use default, which is currently 256 MB. </p>
|
||||
|
||||
</div>
|
||||
@ -233,7 +259,7 @@ Public Attributes</h2></td></tr>
|
||||
</table>
|
||||
</div><div class="memdoc">
|
||||
|
||||
<p>Size of a single memory block to allocate for resources from a small heap <= 512 MB. </p>
|
||||
<p>Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from small heaps <= 512 MB. </p>
|
||||
<p>Set to 0 to use default, which is currently 64 MB. </p>
|
||||
|
||||
</div>
|
||||
|
File diff suppressed because one or more lines are too long
@ -374,15 +374,31 @@ The library uses following algorithm for allocation, in order:
|
||||
|
||||
Please check "CONFIGURATION SECTION" in the code to find macros that you can define
|
||||
before each `#include` of this file or change directly in this file to provide
|
||||
your own implementation of basic facilities like assert, min and max functions,
|
||||
your own implementation of basic facilities like assert, `min()` and `max()` functions,
|
||||
mutex etc. C++ STL is used by default, but changing these allows you to get rid
|
||||
of any STL usage if you want, as many game developers tend to do.
|
||||
|
||||
\subsection custom_memory_allocator Custom memory allocator
|
||||
\subsection custom_memory_allocator Custom host memory allocator
|
||||
|
||||
You can use custom memory allocator by filling optional member
|
||||
VmaAllocatorCreateInfo::pAllocationCallbacks. These functions will be passed to
|
||||
Vulkan, as well as used by the library itself to make any CPU-side allocations.
|
||||
If you use custom allocator for CPU memory rather than default operator `new`
|
||||
and `delete` from C++, you can make this library using your allocator as well
|
||||
by filling optional member VmaAllocatorCreateInfo::pAllocationCallbacks. These
|
||||
functions will be passed to Vulkan, as well as used by the library itself to
|
||||
make any CPU-side allocations.
|
||||
|
||||
\subsection allocation_callbacks Device memory allocation callbacks
|
||||
|
||||
The library makes calls to `vkAllocateMemory()` and `vkFreeMemory()` internally.
|
||||
You can setup callbacks to be informed about these calls, e.g. for the purpose
|
||||
of gathering some statistics. To do it, fill optional member
|
||||
VmaAllocatorCreateInfo::pDeviceMemoryCallbacks.
|
||||
|
||||
\subsection heap_memory_limit Device heap memory limit
|
||||
|
||||
If you want to test how your program behaves with limited amount of Vulkan device
|
||||
memory available (without switching your graphics card to one that really has
|
||||
smaller VRAM), you can use a feature of this library intended for this purpose.
|
||||
To do it, fill optional member VmaAllocatorCreateInfo::pHeapSizeLimit.
|
||||
|
||||
\section thread_safety Thread safety
|
||||
|
||||
@ -458,10 +474,10 @@ typedef struct VmaAllocatorCreateInfo
|
||||
/// Vulkan device.
|
||||
/** It must be valid throughout whole lifetime of created allocator. */
|
||||
VkDevice device;
|
||||
/// Size of a single memory block to allocate for resources.
|
||||
/// Preferred size of a single `VkDeviceMemory` block to be allocated from large heaps.
|
||||
/** Set to 0 to use default, which is currently 256 MB. */
|
||||
VkDeviceSize preferredLargeHeapBlockSize;
|
||||
/// Size of a single memory block to allocate for resources from a small heap <= 512 MB.
|
||||
/// Preferred size of a single `VkDeviceMemory` block to be allocated from small heaps <= 512 MB.
|
||||
/** Set to 0 to use default, which is currently 64 MB. */
|
||||
VkDeviceSize preferredSmallHeapBlockSize;
|
||||
/// Custom CPU memory allocation callbacks.
|
||||
@ -484,6 +500,24 @@ typedef struct VmaAllocatorCreateInfo
|
||||
become lost, set this value to 0.
|
||||
*/
|
||||
uint32_t frameInUseCount;
|
||||
/** \brief Either NULL or a pointer to an array of limits on maximum number of bytes that can be allocated out of particular Vulkan memory heap.
|
||||
|
||||
If not NULL, it must be a pointer to an array of
|
||||
`VkPhysicalDeviceMemoryProperties::memoryHeapCount` elements, defining limit on
|
||||
maximum number of bytes that can be allocated out of particular Vulkan memory
|
||||
heap.
|
||||
|
||||
Any of the elements may be equal to `VK_WHOLE_SIZE`, which means no limit on that
|
||||
heap. This is also the default in case of `pHeapSizeLimit` = NULL.
|
||||
|
||||
If there is a limit defined for a heap:
|
||||
|
||||
- If user tries to allocate more memory from that heap using this allocator,
|
||||
the allocation fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
|
||||
- If the limit is smaller than heap size reported in `VkMemoryHeap::size`, the
|
||||
value of this limit will be reported instead when using vmaGetMemoryProperties().
|
||||
*/
|
||||
const VkDeviceSize* pHeapSizeLimit;
|
||||
} VmaAllocatorCreateInfo;
|
||||
|
||||
/// Creates Allocator object.
|
||||
@ -3372,6 +3406,10 @@ struct VmaAllocator_T
|
||||
// Non-zero when we are inside UnmapPersistentlyMappedMemory...MapPersistentlyMappedMemory.
|
||||
// Counter to allow nested calls to these functions.
|
||||
uint32_t m_UnmapPersistentlyMappedMemoryCounter;
|
||||
|
||||
// Number of bytes free out of limit, or VK_WHOLE_SIZE if not limit for that heap.
|
||||
VkDeviceSize m_HeapSizeLimit[VK_MAX_MEMORY_HEAPS];
|
||||
VMA_MUTEX m_HeapSizeLimitMutex;
|
||||
|
||||
VkPhysicalDeviceProperties m_PhysicalDeviceProperties;
|
||||
VkPhysicalDeviceMemoryProperties m_MemProps;
|
||||
@ -3448,6 +3486,9 @@ struct VmaAllocator_T
|
||||
|
||||
void CreateLostAllocation(VmaAllocation* pAllocation);
|
||||
|
||||
VkResult AllocateVulkanMemory(const VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory);
|
||||
void FreeVulkanMemory(uint32_t memoryType, VkDeviceSize size, VkDeviceMemory hMemory);
|
||||
|
||||
private:
|
||||
VkDeviceSize m_PreferredLargeHeapBlockSize;
|
||||
VkDeviceSize m_PreferredSmallHeapBlockSize;
|
||||
@ -4129,13 +4170,7 @@ void VmaDeviceMemoryBlock::Destroy(VmaAllocator allocator)
|
||||
m_pMappedData = VMA_NULL;
|
||||
}
|
||||
|
||||
// Callback.
|
||||
if(allocator->m_DeviceMemoryCallbacks.pfnFree != VMA_NULL)
|
||||
{
|
||||
(*allocator->m_DeviceMemoryCallbacks.pfnFree)(allocator, m_MemoryTypeIndex, m_hMemory, m_Size);
|
||||
}
|
||||
|
||||
vkFreeMemory(allocator->m_hDevice, m_hMemory, allocator->GetAllocationCallbacks());
|
||||
allocator->FreeVulkanMemory(m_MemoryTypeIndex, m_Size, m_hMemory);
|
||||
m_hMemory = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
@ -5436,7 +5471,7 @@ VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIn
|
||||
allocInfo.allocationSize = blockSize;
|
||||
const VkDevice hDevice = m_hAllocator->m_hDevice;
|
||||
VkDeviceMemory mem = VK_NULL_HANDLE;
|
||||
VkResult res = vkAllocateMemory(hDevice, &allocInfo, m_hAllocator->GetAllocationCallbacks(), &mem);
|
||||
VkResult res = m_hAllocator->AllocateVulkanMemory(&allocInfo, &mem);
|
||||
if(res < 0)
|
||||
{
|
||||
return res;
|
||||
@ -5453,17 +5488,11 @@ VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIn
|
||||
if(res < 0)
|
||||
{
|
||||
VMA_DEBUG_LOG(" vkMapMemory FAILED");
|
||||
vkFreeMemory(hDevice, mem, m_hAllocator->GetAllocationCallbacks());
|
||||
m_hAllocator->FreeVulkanMemory(m_MemoryTypeIndex, blockSize, mem);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// Callback.
|
||||
if(m_hAllocator->m_DeviceMemoryCallbacks.pfnAllocate != VMA_NULL)
|
||||
{
|
||||
(*m_hAllocator->m_DeviceMemoryCallbacks.pfnAllocate)(m_hAllocator, m_MemoryTypeIndex, mem, allocInfo.allocationSize);
|
||||
}
|
||||
|
||||
// Create new Allocation for it.
|
||||
VmaDeviceMemoryBlock* const pBlock = vma_new(m_hAllocator, VmaDeviceMemoryBlock)(m_hAllocator);
|
||||
pBlock->Init(
|
||||
@ -5978,6 +6007,11 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
|
||||
memset(&m_pBlockVectors, 0, sizeof(m_pBlockVectors));
|
||||
memset(&m_pOwnAllocations, 0, sizeof(m_pOwnAllocations));
|
||||
|
||||
for(uint32_t i = 0; i < VK_MAX_MEMORY_HEAPS; ++i)
|
||||
{
|
||||
m_HeapSizeLimit[i] = VK_WHOLE_SIZE;
|
||||
}
|
||||
|
||||
if(pCreateInfo->pDeviceMemoryCallbacks != VMA_NULL)
|
||||
{
|
||||
m_DeviceMemoryCallbacks.pfnAllocate = pCreateInfo->pDeviceMemoryCallbacks->pfnAllocate;
|
||||
@ -5992,6 +6026,22 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
|
||||
m_PreferredSmallHeapBlockSize = (pCreateInfo->preferredSmallHeapBlockSize != 0) ?
|
||||
pCreateInfo->preferredSmallHeapBlockSize : static_cast<VkDeviceSize>(VMA_DEFAULT_SMALL_HEAP_BLOCK_SIZE);
|
||||
|
||||
if(pCreateInfo->pHeapSizeLimit != VMA_NULL)
|
||||
{
|
||||
for(uint32_t heapIndex = 0; heapIndex < GetMemoryHeapCount(); ++heapIndex)
|
||||
{
|
||||
const VkDeviceSize limit = pCreateInfo->pHeapSizeLimit[heapIndex];
|
||||
if(limit != VK_WHOLE_SIZE)
|
||||
{
|
||||
m_HeapSizeLimit[heapIndex] = limit;
|
||||
if(limit < m_MemProps.memoryHeaps[heapIndex].size)
|
||||
{
|
||||
m_MemProps.memoryHeaps[heapIndex].size = limit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
|
||||
{
|
||||
const VkDeviceSize preferredBlockSize = CalcPreferredBlockSize(memTypeIndex);
|
||||
@ -6031,7 +6081,8 @@ VmaAllocator_T::~VmaAllocator_T()
|
||||
|
||||
VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex)
|
||||
{
|
||||
const VkDeviceSize heapSize = m_MemProps.memoryHeaps[MemoryTypeIndexToHeapIndex(memTypeIndex)].size;
|
||||
const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex);
|
||||
const VkDeviceSize heapSize = m_MemProps.memoryHeaps[heapIndex].size;
|
||||
return (heapSize <= VMA_SMALL_HEAP_MAX_SIZE) ?
|
||||
m_PreferredSmallHeapBlockSize : m_PreferredLargeHeapBlockSize;
|
||||
}
|
||||
@ -6128,7 +6179,7 @@ VkResult VmaAllocator_T::AllocateOwnMemory(
|
||||
|
||||
// Allocate VkDeviceMemory.
|
||||
VkDeviceMemory hMemory = VK_NULL_HANDLE;
|
||||
VkResult res = vkAllocateMemory(m_hDevice, &allocInfo, GetAllocationCallbacks(), &hMemory);
|
||||
VkResult res = AllocateVulkanMemory(&allocInfo, &hMemory);
|
||||
if(res < 0)
|
||||
{
|
||||
VMA_DEBUG_LOG(" vkAllocateMemory FAILED");
|
||||
@ -6144,18 +6195,12 @@ VkResult VmaAllocator_T::AllocateOwnMemory(
|
||||
if(res < 0)
|
||||
{
|
||||
VMA_DEBUG_LOG(" vkMapMemory FAILED");
|
||||
vkFreeMemory(m_hDevice, hMemory, GetAllocationCallbacks());
|
||||
FreeVulkanMemory(memTypeIndex, size, hMemory);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Callback.
|
||||
if(m_DeviceMemoryCallbacks.pfnAllocate != VMA_NULL)
|
||||
{
|
||||
(*m_DeviceMemoryCallbacks.pfnAllocate)(this, memTypeIndex, hMemory, size);
|
||||
}
|
||||
|
||||
*pAllocation = vma_new(this, VmaAllocation_T)(m_CurrentFrameIndex.load());
|
||||
(*pAllocation)->InitOwnAllocation(memTypeIndex, hMemory, suballocType, map, pMappedData, size, pUserData);
|
||||
|
||||
@ -6695,6 +6740,57 @@ void VmaAllocator_T::CreateLostAllocation(VmaAllocation* pAllocation)
|
||||
(*pAllocation)->InitLost();
|
||||
}
|
||||
|
||||
VkResult VmaAllocator_T::AllocateVulkanMemory(const VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory)
|
||||
{
|
||||
const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(pAllocateInfo->memoryTypeIndex);
|
||||
|
||||
VkResult res;
|
||||
if(m_HeapSizeLimit[heapIndex] != VK_WHOLE_SIZE)
|
||||
{
|
||||
VmaMutexLock lock(m_HeapSizeLimitMutex, m_UseMutex);
|
||||
if(m_HeapSizeLimit[heapIndex] >= pAllocateInfo->allocationSize)
|
||||
{
|
||||
res = vkAllocateMemory(m_hDevice, pAllocateInfo, GetAllocationCallbacks(), pMemory);
|
||||
if(res == VK_SUCCESS)
|
||||
{
|
||||
m_HeapSizeLimit[heapIndex] -= pAllocateInfo->allocationSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res = VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res = vkAllocateMemory(m_hDevice, pAllocateInfo, GetAllocationCallbacks(), pMemory);
|
||||
}
|
||||
|
||||
if(res == VK_SUCCESS && m_DeviceMemoryCallbacks.pfnAllocate != VMA_NULL)
|
||||
{
|
||||
(*m_DeviceMemoryCallbacks.pfnAllocate)(this, pAllocateInfo->memoryTypeIndex, *pMemory, pAllocateInfo->allocationSize);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void VmaAllocator_T::FreeVulkanMemory(uint32_t memoryType, VkDeviceSize size, VkDeviceMemory hMemory)
|
||||
{
|
||||
if(m_DeviceMemoryCallbacks.pfnFree != VMA_NULL)
|
||||
{
|
||||
(*m_DeviceMemoryCallbacks.pfnFree)(this, memoryType, hMemory, size);
|
||||
}
|
||||
|
||||
vkFreeMemory(m_hDevice, hMemory, GetAllocationCallbacks());
|
||||
|
||||
const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memoryType);
|
||||
if(m_HeapSizeLimit[heapIndex] != VK_WHOLE_SIZE)
|
||||
{
|
||||
VmaMutexLock lock(m_HeapSizeLimitMutex, m_UseMutex);
|
||||
m_HeapSizeLimit[heapIndex] += size;
|
||||
}
|
||||
}
|
||||
|
||||
void VmaAllocator_T::FreeOwnMemory(VmaAllocation allocation)
|
||||
{
|
||||
VMA_ASSERT(allocation && allocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_OWN);
|
||||
@ -6710,18 +6806,12 @@ void VmaAllocator_T::FreeOwnMemory(VmaAllocation allocation)
|
||||
|
||||
VkDeviceMemory hMemory = allocation->GetMemory();
|
||||
|
||||
// Callback.
|
||||
if(m_DeviceMemoryCallbacks.pfnFree != VMA_NULL)
|
||||
{
|
||||
(*m_DeviceMemoryCallbacks.pfnFree)(this, memTypeIndex, hMemory, allocation->GetSize());
|
||||
}
|
||||
|
||||
if(allocation->GetMappedData() != VMA_NULL)
|
||||
{
|
||||
vkUnmapMemory(m_hDevice, hMemory);
|
||||
}
|
||||
|
||||
vkFreeMemory(m_hDevice, hMemory, GetAllocationCallbacks());
|
||||
FreeVulkanMemory(memTypeIndex, allocation->GetSize(), hMemory);
|
||||
|
||||
VMA_DEBUG_LOG(" Freed OwnMemory MemoryTypeIndex=%u", memTypeIndex);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user