Added support for VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT without HOST_VISIBLE.

Implemented usage of VK_KHR_dedicated_allocation.
Renamed "own allocation" to "dedicated allocation" everywhere.
This commit is contained in:
Adam Sawicki 2017-10-02 18:31:03 +02:00
parent 1bb85fa719
commit 5db51b1264
18 changed files with 451 additions and 236 deletions

View File

@ -41,6 +41,7 @@ Additional features:
- Customization: Predefine appropriate macros to provide your own implementation of all external facilities used by the library, from assert, mutex, and atomic, to vector and linked list.
- Support for persistently mapped memory: Just allocate memory with appropriate flag and you get access to mapped pointer.
- Custom memory pools: Create a pool with desired parameters (e.g. fixed or limited maximum size) and allocate memory out of it.
- Support for VK_KHR_dedicated_allocation extension.
- Defragmentation: Call one function and let the library move data around to free some memory blocks and make your allocations better compacted.
- Lost allocations: Allocate memory with appropriate flags and let the library remove allocations that are not used for many frames to make room for new ones.
- Statistics: Obtain detailed statistics about the amount of memory used, unused, number of allocated blocks, number of allocations etc. - globally, per memory heap, and per memory type.

Binary file not shown.

View File

@ -279,9 +279,15 @@ $(function() {
<li>vkGetBufferMemoryRequirements
: <a class="el" href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143">VmaVulkanFunctions</a>
</li>
<li>vkGetBufferMemoryRequirements2KHR
: <a class="el" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">VmaVulkanFunctions</a>
</li>
<li>vkGetImageMemoryRequirements
: <a class="el" href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4">VmaVulkanFunctions</a>
</li>
<li>vkGetImageMemoryRequirements2KHR
: <a class="el" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">VmaVulkanFunctions</a>
</li>
<li>vkGetPhysicalDeviceMemoryProperties
: <a class="el" href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830">VmaVulkanFunctions</a>
</li>

View File

@ -279,9 +279,15 @@ $(function() {
<li>vkGetBufferMemoryRequirements
: <a class="el" href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143">VmaVulkanFunctions</a>
</li>
<li>vkGetBufferMemoryRequirements2KHR
: <a class="el" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">VmaVulkanFunctions</a>
</li>
<li>vkGetImageMemoryRequirements
: <a class="el" href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4">VmaVulkanFunctions</a>
</li>
<li>vkGetImageMemoryRequirements2KHR
: <a class="el" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">VmaVulkanFunctions</a>
</li>
<li>vkGetPhysicalDeviceMemoryProperties
: <a class="el" href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830">VmaVulkanFunctions</a>
</li>

View File

@ -77,15 +77,15 @@ $(function() {
<li>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT
: <a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">vk_mem_alloc.h</a>
</li>
<li>VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
: <a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">vk_mem_alloc.h</a>
</li>
<li>VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM
: <a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882">vk_mem_alloc.h</a>
</li>
<li>VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT
: <a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">vk_mem_alloc.h</a>
</li>
<li>VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT
: <a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a965e035b69f8728b317803ef2d523aa4">vk_mem_alloc.h</a>
</li>
<li>VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT
: <a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597ae443691ef3d077c0dc3de5576ac4c312">vk_mem_alloc.h</a>
</li>
@ -95,6 +95,9 @@ $(function() {
<li>VMA_ALLOCATOR_FLAG_BITS_MAX_ENUM
: <a class="el" href="group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fa914e905a08c2e578f76b9d6c418626cc">vk_mem_alloc.h</a>
</li>
<li>VMA_ALLOCATOR_KHR_DEDICATED_ALLOCATION_BIT
: <a class="el" href="group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fa96990602a42bd78d27fb25e2265880b4">vk_mem_alloc.h</a>
</li>
<li>VMA_MEMORY_USAGE_CPU_ONLY
: <a class="el" href="group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">vk_mem_alloc.h</a>
</li>

View File

@ -65,15 +65,15 @@ $(function() {
<li>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT
: <a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">vk_mem_alloc.h</a>
</li>
<li>VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
: <a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">vk_mem_alloc.h</a>
</li>
<li>VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM
: <a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882">vk_mem_alloc.h</a>
</li>
<li>VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT
: <a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">vk_mem_alloc.h</a>
</li>
<li>VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT
: <a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a965e035b69f8728b317803ef2d523aa4">vk_mem_alloc.h</a>
</li>
<li>VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT
: <a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597ae443691ef3d077c0dc3de5576ac4c312">vk_mem_alloc.h</a>
</li>
@ -83,6 +83,9 @@ $(function() {
<li>VMA_ALLOCATOR_FLAG_BITS_MAX_ENUM
: <a class="el" href="group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fa914e905a08c2e578f76b9d6c418626cc">vk_mem_alloc.h</a>
</li>
<li>VMA_ALLOCATOR_KHR_DEDICATED_ALLOCATION_BIT
: <a class="el" href="group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fa96990602a42bd78d27fb25e2265880b4">vk_mem_alloc.h</a>
</li>
<li>VMA_MEMORY_USAGE_CPU_ONLY
: <a class="el" href="group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">vk_mem_alloc.h</a>
</li>

View File

@ -124,6 +124,7 @@ Typedefs</h2></td></tr>
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="enum-members"></a>
Enumerations</h2></td></tr>
<tr class="memitem:ga34fff29c218d23a7ff7dff44b77b6b6f"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#ga34fff29c218d23a7ff7dff44b77b6b6f">VmaAllocatorFlagBits</a> { <a class="el" href="group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fabe92b706180652ceb320da5bc383aef4">VMA_ALLOCATOR_EXTERNALLY_SYNCHRONIZED_BIT</a> = 0x00000001,
<a class="el" href="group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fa96990602a42bd78d27fb25e2265880b4">VMA_ALLOCATOR_KHR_DEDICATED_ALLOCATION_BIT</a> = 0x00000002,
<a class="el" href="group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fa914e905a08c2e578f76b9d6c418626cc">VMA_ALLOCATOR_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF
}<tr class="memdesc:ga34fff29c218d23a7ff7dff44b77b6b6f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags for created VmaAllocator. <a href="group__general.html#ga34fff29c218d23a7ff7dff44b77b6b6f">More...</a><br /></td></tr>
</td></tr>
@ -336,6 +337,19 @@ Functions</h2></td></tr>
<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="gga34fff29c218d23a7ff7dff44b77b6b6fabe92b706180652ceb320da5bc383aef4"></a>VMA_ALLOCATOR_EXTERNALLY_SYNCHRONIZED_BIT&#160;</td><td class="fielddoc"><p>Allocator and all objects created from it will not be synchronized internally, so you must guarantee they are used from only one thread at a time or synchronized externally by you. </p>
<p>Using this flag may increase performance because internal mutexes are not used. </p>
</td></tr>
<tr><td class="fieldname"><a id="gga34fff29c218d23a7ff7dff44b77b6b6fa96990602a42bd78d27fb25e2265880b4"></a>VMA_ALLOCATOR_KHR_DEDICATED_ALLOCATION_BIT&#160;</td><td class="fielddoc"><p>Enables usage of VK_KHR_dedicated_allocation extension. </p>
<p>Using this extenion will automatically allocate dedicated blocks of memory for some buffers and images instead of suballocating place for them out of bigger memory blocks (as if you explicitly used VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT flag) when it is recommended by the driver. It may improve performance on some GPUs.</p>
<p>You may set this flag only if you found out that following device extensions are supported, you enabled them while creating Vulkan device passed as <a class="el" href="struct_vma_allocator_create_info.html#ad924ddd77b04039c88d0c09b0ffcd500" title="Vulkan device. ">VmaAllocatorCreateInfo::device</a>, and you want them to be used internally by this library:</p>
<ul>
<li>VK_KHR_get_memory_requirements2</li>
<li>VK_KHR_dedicated_allocation</li>
</ul>
<p>If this flag is enabled, you must also provide <a class="el" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd" title="Pointers to Vulkan functions. Can be null if you leave define VMA_STATIC_VULKAN_FUNCTIONS 1...">VmaAllocatorCreateInfo::pVulkanFunctions</a> and fill at least members: <a class="el" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">VmaVulkanFunctions::vkGetBufferMemoryRequirements2KHR</a>, <a class="el" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">VmaVulkanFunctions::vkGetImageMemoryRequirements2KHR</a>, because they are never imported statically.</p>
<p>When this flag is set, you can experience following warnings reported by Vulkan validation layer. You can ignore them.</p>
<blockquote class="doxtable">
<p>vkBindBufferMemory(): Binding memory to buffer 0x2d but vkGetBufferMemoryRequirements() has not been called on that buffer.</p>
</blockquote>
</td></tr>
<tr><td class="fieldname"><a id="gga34fff29c218d23a7ff7dff44b77b6b6fa914e905a08c2e578f76b9d6c418626cc"></a>VMA_ALLOCATOR_FLAG_BITS_MAX_ENUM&#160;</td><td class="fielddoc"></td></tr>
</table>

View File

@ -99,7 +99,7 @@ Enumerations</h2></td></tr>
}</td></tr>
<tr class="separator:gaa5846affa1e9da3800e3e78fae2305cc"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gad9889c10c798b040d59c92f257cae597"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer1.html#gad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a> { <br />
&#160;&#160;<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a965e035b69f8728b317803ef2d523aa4">VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT</a> = 0x00000001,
&#160;&#160;<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> = 0x00000001,
<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a> = 0x00000002,
<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597ae443691ef3d077c0dc3de5576ac4c312">VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT</a> = 0x00000004,
<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> = 0x00000008,
@ -191,14 +191,14 @@ Functions</h2></td></tr>
<p>Flags to be passed as <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a>. </p>
<table class="fieldtable">
<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="ggad9889c10c798b040d59c92f257cae597a965e035b69f8728b317803ef2d523aa4"></a>VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT&#160;</td><td class="fielddoc"><p>Set this flag if the allocation should have its own memory block. </p>
<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f"></a>VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT&#160;</td><td class="fielddoc"><p>Set this flag if the allocation should have its own memory block. </p>
<p>Use it for special, big resources, like fullscreen images used as attachments.</p>
<p>This flag must also be used for host visible resources that you want to map simultaneously because otherwise they might end up as regions of the same <code>VkDeviceMemory</code>, while mapping same <code>VkDeviceMemory</code> multiple times simultaneously is illegal.</p>
<p>You should not use this flag if <a class="el" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150" title="Pool that this allocation should be created in. ">VmaAllocationCreateInfo::pool</a> is not null. </p>
</td></tr>
<tr><td class="fieldname"><a id="ggad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff"></a>VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT&#160;</td><td class="fielddoc"><p>Set this flag to only try to allocate from existing <code>VkDeviceMemory</code> blocks and never create new such block. </p>
<p>If new allocation cannot be placed in any of the existing blocks, allocation fails with <code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code> error.</p>
<p>You should not use <code>VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT</code> and <code>VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</code> at the same time. It makes no sense.</p>
<p>You should not use <code>VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</code> and <code>VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</code> at the same time. It makes no sense.</p>
<p>If <a class="el" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150" title="Pool that this allocation should be created in. ">VmaAllocationCreateInfo::pool</a> is not null, this flag is implied and ignored. </p>
</td></tr>
<tr><td class="fieldname"><a id="ggad9889c10c798b040d59c92f257cae597ae443691ef3d077c0dc3de5576ac4c312"></a>VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT&#160;</td><td class="fielddoc"><p>Set this flag to use a memory that will be persistently mapped and retrieve pointer to it. </p>

View File

@ -609,7 +609,7 @@ Functions</h2></td></tr>
<p>This function works by moving allocations to different places (different <code>VkDeviceMemory</code> objects and/or different offsets) in order to optimize memory usage. Only allocations that are in pAllocations array can be moved. All other allocations are considered nonmovable in this call. Basic rules:</p>
<ul>
<li>Only allocations made in memory types that have <code>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</code> flag can be compacted. You may pass other allocations but it makes no sense - these will never be moved.</li>
<li>You may pass allocations made with <code>VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT</code> but it makes no sense - they will never be moved.</li>
<li>You may pass allocations made with <code>VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</code> but it makes no sense - they will never be moved.</li>
<li>Both allocations made with or without <code>VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT</code> flag can be compacted. If not persistently mapped, memory will be mapped temporarily inside this function if needed, so it shouldn't be mapped by you for the time of this call.</li>
<li>You must not pass same <code>VmaAllocation</code> object multiple times in pAllocations array.</li>
</ul>

View File

@ -259,7 +259,7 @@ void MyBuffer::EnsureBuffer()
<li>If failed, try to create a new block of <code>VkDeviceMemory</code>, with preferred block size.</li>
<li>If failed, try to create such block with size/2 and size/4.</li>
<li>If failed and <code>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</code> flag was specified, try to find space in existing blocks, possilby making some other allocations lost.</li>
<li>If failed, try to allocate separate <code>VkDeviceMemory</code> for this allocation, just like when you use <code>VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT</code>.</li>
<li>If failed, try to allocate separate <code>VkDeviceMemory</code> for this allocation, just like when you use <code>VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</code>.</li>
<li>If failed, choose other memory type that meets the requirements specified in <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> and go to point 1.</li>
<li>If failed, return <code>VK_ERROR_OUT_OF_DEVICE_MEMORY</code>.</li>
</ol>

View File

@ -11,19 +11,22 @@ var searchData=
['vkdestroyimage',['vkDestroyImage',['../struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa',1,'VmaVulkanFunctions']]],
['vkfreememory',['vkFreeMemory',['../struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4',1,'VmaVulkanFunctions']]],
['vkgetbuffermemoryrequirements',['vkGetBufferMemoryRequirements',['../struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143',1,'VmaVulkanFunctions']]],
['vkgetbuffermemoryrequirements2khr',['vkGetBufferMemoryRequirements2KHR',['../struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c',1,'VmaVulkanFunctions']]],
['vkgetimagememoryrequirements',['vkGetImageMemoryRequirements',['../struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4',1,'VmaVulkanFunctions']]],
['vkgetimagememoryrequirements2khr',['vkGetImageMemoryRequirements2KHR',['../struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875',1,'VmaVulkanFunctions']]],
['vkgetphysicaldevicememoryproperties',['vkGetPhysicalDeviceMemoryProperties',['../struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830',1,'VmaVulkanFunctions']]],
['vkgetphysicaldeviceproperties',['vkGetPhysicalDeviceProperties',['../struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96',1,'VmaVulkanFunctions']]],
['vkmapmemory',['vkMapMemory',['../struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49',1,'VmaVulkanFunctions']]],
['vkunmapmemory',['vkUnmapMemory',['../struct_vma_vulkan_functions.html#acc798589736f0becb317fc2196c1d8b9',1,'VmaVulkanFunctions']]],
['vma_5fallocation_5fcreate_5fcan_5fbecome_5flost_5fbit',['VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fcan_5fmake_5fother_5flost_5fbit',['VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fdedicated_5fmemory_5fbit',['VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fflag_5fbits_5fmax_5fenum',['VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fnever_5fallocate_5fbit',['VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fown_5fmemory_5fbit',['VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597a965e035b69f8728b317803ef2d523aa4',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fpersistent_5fmap_5fbit',['VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597ae443691ef3d077c0dc3de5576ac4c312',1,'vk_mem_alloc.h']]],
['vma_5fallocator_5fexternally_5fsynchronized_5fbit',['VMA_ALLOCATOR_EXTERNALLY_SYNCHRONIZED_BIT',['../group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fabe92b706180652ceb320da5bc383aef4',1,'vk_mem_alloc.h']]],
['vma_5fallocator_5fflag_5fbits_5fmax_5fenum',['VMA_ALLOCATOR_FLAG_BITS_MAX_ENUM',['../group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fa914e905a08c2e578f76b9d6c418626cc',1,'vk_mem_alloc.h']]],
['vma_5fallocator_5fkhr_5fdedicated_5fallocation_5fbit',['VMA_ALLOCATOR_KHR_DEDICATED_ALLOCATION_BIT',['../group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fa96990602a42bd78d27fb25e2265880b4',1,'vk_mem_alloc.h']]],
['vma_5fmemory_5fusage_5fcpu_5fonly',['VMA_MEMORY_USAGE_CPU_ONLY',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5',1,'vk_mem_alloc.h']]],
['vma_5fmemory_5fusage_5fcpu_5fto_5fgpu',['VMA_MEMORY_USAGE_CPU_TO_GPU',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67',1,'vk_mem_alloc.h']]],
['vma_5fmemory_5fusage_5fgpu_5fonly',['VMA_MEMORY_USAGE_GPU_ONLY',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7',1,'vk_mem_alloc.h']]],

View File

@ -2,12 +2,13 @@ var searchData=
[
['vma_5fallocation_5fcreate_5fcan_5fbecome_5flost_5fbit',['VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fcan_5fmake_5fother_5flost_5fbit',['VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fdedicated_5fmemory_5fbit',['VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fflag_5fbits_5fmax_5fenum',['VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fnever_5fallocate_5fbit',['VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fown_5fmemory_5fbit',['VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597a965e035b69f8728b317803ef2d523aa4',1,'vk_mem_alloc.h']]],
['vma_5fallocation_5fcreate_5fpersistent_5fmap_5fbit',['VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT',['../group__layer1.html#ggad9889c10c798b040d59c92f257cae597ae443691ef3d077c0dc3de5576ac4c312',1,'vk_mem_alloc.h']]],
['vma_5fallocator_5fexternally_5fsynchronized_5fbit',['VMA_ALLOCATOR_EXTERNALLY_SYNCHRONIZED_BIT',['../group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fabe92b706180652ceb320da5bc383aef4',1,'vk_mem_alloc.h']]],
['vma_5fallocator_5fflag_5fbits_5fmax_5fenum',['VMA_ALLOCATOR_FLAG_BITS_MAX_ENUM',['../group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fa914e905a08c2e578f76b9d6c418626cc',1,'vk_mem_alloc.h']]],
['vma_5fallocator_5fkhr_5fdedicated_5fallocation_5fbit',['VMA_ALLOCATOR_KHR_DEDICATED_ALLOCATION_BIT',['../group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fa96990602a42bd78d27fb25e2265880b4',1,'vk_mem_alloc.h']]],
['vma_5fmemory_5fusage_5fcpu_5fonly',['VMA_MEMORY_USAGE_CPU_ONLY',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5',1,'vk_mem_alloc.h']]],
['vma_5fmemory_5fusage_5fcpu_5fto_5fgpu',['VMA_MEMORY_USAGE_CPU_TO_GPU',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67',1,'vk_mem_alloc.h']]],
['vma_5fmemory_5fusage_5fgpu_5fonly',['VMA_MEMORY_USAGE_GPU_ONLY',['../group__layer1.html#ggaa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7',1,'vk_mem_alloc.h']]],

View File

@ -9,7 +9,9 @@ var searchData=
['vkdestroyimage',['vkDestroyImage',['../struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa',1,'VmaVulkanFunctions']]],
['vkfreememory',['vkFreeMemory',['../struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4',1,'VmaVulkanFunctions']]],
['vkgetbuffermemoryrequirements',['vkGetBufferMemoryRequirements',['../struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143',1,'VmaVulkanFunctions']]],
['vkgetbuffermemoryrequirements2khr',['vkGetBufferMemoryRequirements2KHR',['../struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c',1,'VmaVulkanFunctions']]],
['vkgetimagememoryrequirements',['vkGetImageMemoryRequirements',['../struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4',1,'VmaVulkanFunctions']]],
['vkgetimagememoryrequirements2khr',['vkGetImageMemoryRequirements2KHR',['../struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875',1,'VmaVulkanFunctions']]],
['vkgetphysicaldevicememoryproperties',['vkGetPhysicalDeviceMemoryProperties',['../struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830',1,'VmaVulkanFunctions']]],
['vkgetphysicaldeviceproperties',['vkGetPhysicalDeviceProperties',['../struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96',1,'VmaVulkanFunctions']]],
['vkmapmemory',['vkMapMemory',['../struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49',1,'VmaVulkanFunctions']]],

View File

@ -74,7 +74,9 @@ $(function() {
<tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa">vkDestroyImage</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
<tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a4c658701778564d62034255b5dda91b4">vkFreeMemory</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a5b92901df89a4194b0d12f6071d4d143">vkGetBufferMemoryRequirements</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
<tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4">vkGetImageMemoryRequirements</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
<tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">vkGetBufferMemoryRequirements2KHR</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a475f6f49f8debe4d10800592606d53f4">vkGetImageMemoryRequirements</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
<tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">vkGetImageMemoryRequirements2KHR</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a60d25c33bba06bb8592e6875cbaa9830">vkGetPhysicalDeviceMemoryProperties</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
<tr><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#a77b7a74082823e865dd6546623468f96">vkGetPhysicalDeviceProperties</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html#ab5c1f38dea3a2cf00dc9eb4f57218c49">vkMapMemory</a></td><td class="entry"><a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a></td><td class="entry"></td></tr>

View File

@ -101,6 +101,10 @@ Public Attributes</h2></td></tr>
<tr class="separator:a23ebe70be515b9b5010a1d691200e325"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a90b898227039b1dcb3520f6e91f09ffa"><td class="memItemLeft" align="right" valign="top">PFN_vkDestroyImage&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html#a90b898227039b1dcb3520f6e91f09ffa">vkDestroyImage</a></td></tr>
<tr class="separator:a90b898227039b1dcb3520f6e91f09ffa"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9d8d1b05d2b1e7e1d9b27f6f585acf9c"><td class="memItemLeft" align="right" valign="top">PFN_vkGetBufferMemoryRequirements2KHR&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">vkGetBufferMemoryRequirements2KHR</a></td></tr>
<tr class="separator:a9d8d1b05d2b1e7e1d9b27f6f585acf9c"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9cdcdc1e2b2ea7c571f7d27e30ba6875"><td class="memItemLeft" align="right" valign="top">PFN_vkGetImageMemoryRequirements2KHR&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_vulkan_functions.html#a9cdcdc1e2b2ea7c571f7d27e30ba6875">vkGetImageMemoryRequirements2KHR</a></td></tr>
<tr class="separator:a9cdcdc1e2b2ea7c571f7d27e30ba6875"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>Pointers to some Vulkan functions - a subset used by the library. </p>
@ -230,6 +234,20 @@ Public Attributes</h2></td></tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a9d8d1b05d2b1e7e1d9b27f6f585acf9c"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9d8d1b05d2b1e7e1d9b27f6f585acf9c">&#9670;&nbsp;</a></span>vkGetBufferMemoryRequirements2KHR</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">PFN_vkGetBufferMemoryRequirements2KHR VmaVulkanFunctions::vkGetBufferMemoryRequirements2KHR</td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a475f6f49f8debe4d10800592606d53f4"></a>
@ -244,6 +262,20 @@ Public Attributes</h2></td></tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a9cdcdc1e2b2ea7c571f7d27e30ba6875"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9cdcdc1e2b2ea7c571f7d27e30ba6875">&#9670;&nbsp;</a></span>vkGetImageMemoryRequirements2KHR</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">PFN_vkGetImageMemoryRequirements2KHR VmaVulkanFunctions::vkGetImageMemoryRequirements2KHR</td>
</tr>
</table>
</div><div class="memdoc">
</div>
</div>
<a id="a60d25c33bba06bb8592e6875cbaa9830"></a>

View File

@ -173,6 +173,7 @@ Typedefs</h2></td></tr>
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="enum-members"></a>
Enumerations</h2></td></tr>
<tr class="memitem:ga34fff29c218d23a7ff7dff44b77b6b6f"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__general.html#ga34fff29c218d23a7ff7dff44b77b6b6f">VmaAllocatorFlagBits</a> { <a class="el" href="group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fabe92b706180652ceb320da5bc383aef4">VMA_ALLOCATOR_EXTERNALLY_SYNCHRONIZED_BIT</a> = 0x00000001,
<a class="el" href="group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fa96990602a42bd78d27fb25e2265880b4">VMA_ALLOCATOR_KHR_DEDICATED_ALLOCATION_BIT</a> = 0x00000002,
<a class="el" href="group__general.html#gga34fff29c218d23a7ff7dff44b77b6b6fa914e905a08c2e578f76b9d6c418626cc">VMA_ALLOCATOR_FLAG_BITS_MAX_ENUM</a> = 0x7FFFFFFF
}<tr class="memdesc:ga34fff29c218d23a7ff7dff44b77b6b6f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flags for created VmaAllocator. <a href="group__general.html#ga34fff29c218d23a7ff7dff44b77b6b6f">More...</a><br /></td></tr>
</td></tr>
@ -189,7 +190,7 @@ Enumerations</h2></td></tr>
}</td></tr>
<tr class="separator:gaa5846affa1e9da3800e3e78fae2305cc"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gad9889c10c798b040d59c92f257cae597"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__layer1.html#gad9889c10c798b040d59c92f257cae597">VmaAllocationCreateFlagBits</a> { <br />
&#160;&#160;<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a965e035b69f8728b317803ef2d523aa4">VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT</a> = 0x00000001,
&#160;&#160;<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> = 0x00000001,
<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a> = 0x00000002,
<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597ae443691ef3d077c0dc3de5576ac4c312">VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT</a> = 0x00000004,
<a class="el" href="group__layer1.html#ggad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> = 0x00000008,

File diff suppressed because one or more lines are too long

View File

@ -31,7 +31,7 @@ extern "C" {
\tableofcontents
<b>Version 2.0.0-alpha.3</b> (2017-09-12)
<b>Version 2.0.0-alpha.4</b> (2017-10-02)
Source repository: [VulkanMemoryAllocator project on GitHub](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator) \n
Product page: [Vulkan Memory Allocator on GPUOpen](https://gpuopen.com/gaming-product/vulkan-memory-allocator/)
@ -328,7 +328,7 @@ The library uses following algorithm for allocation, in order:
specified, try to find space in existing blocks, possilby making some other
allocations lost.
-# If failed, try to allocate separate `VkDeviceMemory` for this allocation,
just like when you use `VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT`.
just like when you use `VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT`.
-# If failed, choose other memory type that meets the requirements specified in
VmaAllocationCreateInfo and go to point 1.
-# If failed, return `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
@ -433,6 +433,34 @@ typedef enum VmaAllocatorFlagBits {
Using this flag may increase performance because internal mutexes are not used.
*/
VMA_ALLOCATOR_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001,
/** \brief Enables usage of VK_KHR_dedicated_allocation extension.
Using this extenion will automatically allocate dedicated blocks of memory for
some buffers and images instead of suballocating place for them out of bigger
memory blocks (as if you explicitly used VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
flag) when it is recommended by the driver. It may improve performance on some
GPUs.
You may set this flag only if you found out that following device extensions are
supported, you enabled them while creating Vulkan device passed as
VmaAllocatorCreateInfo::device, and you want them to be used internally by this
library:
- VK_KHR_get_memory_requirements2
- VK_KHR_dedicated_allocation
If this flag is enabled, you must also provide
VmaAllocatorCreateInfo::pVulkanFunctions and fill at least members:
VmaVulkanFunctions::vkGetBufferMemoryRequirements2KHR,
VmaVulkanFunctions::vkGetImageMemoryRequirements2KHR, because they are never
imported statically.
When this flag is set, you can experience following warnings reported by Vulkan
validation layer. You can ignore them.
> vkBindBufferMemory(): Binding memory to buffer 0x2d but vkGetBufferMemoryRequirements() has not been called on that buffer.
*/
VMA_ALLOCATOR_KHR_DEDICATED_ALLOCATION_BIT = 0x00000002,
VMA_ALLOCATOR_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VmaAllocatorFlagBits;
@ -457,6 +485,8 @@ typedef struct VmaVulkanFunctions {
PFN_vkDestroyBuffer vkDestroyBuffer;
PFN_vkCreateImage vkCreateImage;
PFN_vkDestroyImage vkDestroyImage;
PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR;
PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR;
} VmaVulkanFunctions;
/// Description of a Allocator to be created.
@ -665,14 +695,14 @@ typedef enum VmaAllocationCreateFlagBits {
You should not use this flag if VmaAllocationCreateInfo::pool is not null.
*/
VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT = 0x00000001,
VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT = 0x00000001,
/** \brief Set this flag to only try to allocate from existing `VkDeviceMemory` blocks and never create new such block.
If new allocation cannot be placed in any of the existing blocks, allocation
fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY` error.
You should not use `VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT` and
You should not use `VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT` and
`VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT` at the same time. It makes no sense.
If VmaAllocationCreateInfo::pool is not null, this flag is implied and ignored. */
@ -1116,7 +1146,7 @@ allocations are considered nonmovable in this call. Basic rules:
- Only allocations made in memory types that have
`VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` flag can be compacted. You may pass other
allocations but it makes no sense - these will never be moved.
- You may pass allocations made with `VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT` but
- You may pass allocations made with `VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT` but
it makes no sense - they will never be moved.
- Both allocations made with or without `VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT`
flag can be compacted. If not persistently mapped, memory will be mapped
@ -1453,12 +1483,12 @@ If providing your own implementation, you need to implement a subset of std::ato
#define VMA_BEST_FIT (1)
#endif
#ifndef VMA_DEBUG_ALWAYS_OWN_MEMORY
#ifndef VMA_DEBUG_ALWAYS_DEDICATED_MEMORY
/**
Every object will have its own allocation.
Every allocation will have its own memory block.
Define to 1 for debugging purposes only.
*/
#define VMA_DEBUG_ALWAYS_OWN_MEMORY (0)
#define VMA_DEBUG_ALWAYS_DEDICATED_MEMORY (0)
#endif
#ifndef VMA_DEBUG_ALIGNMENT
@ -2826,7 +2856,7 @@ public:
{
ALLOCATION_TYPE_NONE,
ALLOCATION_TYPE_BLOCK,
ALLOCATION_TYPE_OWN,
ALLOCATION_TYPE_DEDICATED,
};
VmaAllocation_T(uint32_t currentFrameIndex) :
@ -2883,7 +2913,7 @@ public:
m_BlockAllocation.m_Offset = offset;
}
void InitOwnAllocation(
void InitDedicatedAllocation(
uint32_t memoryTypeIndex,
VkDeviceMemory hMemory,
VmaSuballocationType suballocationType,
@ -2894,15 +2924,15 @@ public:
{
VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE);
VMA_ASSERT(hMemory != VK_NULL_HANDLE);
m_Type = ALLOCATION_TYPE_OWN;
m_Type = ALLOCATION_TYPE_DEDICATED;
m_Alignment = 0;
m_Size = size;
m_pUserData = pUserData;
m_SuballocationType = suballocationType;
m_OwnAllocation.m_MemoryTypeIndex = memoryTypeIndex;
m_OwnAllocation.m_hMemory = hMemory;
m_OwnAllocation.m_PersistentMap = persistentMap;
m_OwnAllocation.m_pMappedData = pMappedData;
m_DedicatedAllocation.m_MemoryTypeIndex = memoryTypeIndex;
m_DedicatedAllocation.m_hMemory = hMemory;
m_DedicatedAllocation.m_PersistentMap = persistentMap;
m_DedicatedAllocation.m_pMappedData = pMappedData;
}
ALLOCATION_TYPE GetType() const { return m_Type; }
@ -2925,8 +2955,8 @@ public:
bool CanBecomeLost() const;
VmaPool GetPool() const;
VkResult OwnAllocMapPersistentlyMappedMemory(VmaAllocator hAllocator);
void OwnAllocUnmapPersistentlyMappedMemory(VmaAllocator hAllocator);
VkResult DedicatedAllocMapPersistentlyMappedMemory(VmaAllocator hAllocator);
void DedicatedAllocUnmapPersistentlyMappedMemory(VmaAllocator hAllocator);
uint32_t GetLastUseFrameIndex() const
{
@ -2946,9 +2976,9 @@ public:
*/
bool MakeLost(uint32_t currentFrameIndex, uint32_t frameInUseCount);
void OwnAllocCalcStatsInfo(VmaStatInfo& outInfo)
void DedicatedAllocCalcStatsInfo(VmaStatInfo& outInfo)
{
VMA_ASSERT(m_Type == ALLOCATION_TYPE_OWN);
VMA_ASSERT(m_Type == ALLOCATION_TYPE_DEDICATED);
outInfo.blockCount = 1;
outInfo.allocationCount = 1;
outInfo.unusedRangeCount = 0;
@ -2977,7 +3007,7 @@ private:
};
// Allocation for an object that has its own private VkDeviceMemory.
struct OwnAllocation
struct DedicatedAllocation
{
uint32_t m_MemoryTypeIndex;
VkDeviceMemory m_hMemory;
@ -2990,7 +3020,7 @@ private:
// Allocation out of VmaDeviceMemoryBlock.
BlockAllocation m_BlockAllocation;
// Allocation for an object that has its own private VkDeviceMemory.
OwnAllocation m_OwnAllocation;
DedicatedAllocation m_DedicatedAllocation;
};
};
@ -3436,6 +3466,7 @@ public:
struct VmaAllocator_T
{
bool m_UseMutex;
bool m_UseKhrDedicatedAllocation;
VkDevice m_hDevice;
bool m_AllocationCallbacksSpecified;
VkAllocationCallbacks m_AllocationCallbacks;
@ -3456,8 +3487,8 @@ struct VmaAllocator_T
// Each vector is sorted by memory (handle value).
typedef VmaVector< VmaAllocation, VmaStlAllocator<VmaAllocation> > AllocationVectorType;
AllocationVectorType* m_pOwnAllocations[VK_MAX_MEMORY_TYPES][VMA_BLOCK_VECTOR_TYPE_COUNT];
VMA_MUTEX m_OwnAllocationsMutex[VK_MAX_MEMORY_TYPES];
AllocationVectorType* m_pDedicatedAllocations[VK_MAX_MEMORY_TYPES][VMA_BLOCK_VECTOR_TYPE_COUNT];
VMA_MUTEX m_DedicatedAllocationsMutex[VK_MAX_MEMORY_TYPES];
VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo);
~VmaAllocator_T();
@ -3487,9 +3518,19 @@ struct VmaAllocator_T
return m_MemProps.memoryTypes[memTypeIndex].heapIndex;
}
void GetBufferMemoryRequirements(
VkBuffer hBuffer,
VkMemoryRequirements& memReq,
bool& dedicatedAllocation) const;
void GetImageMemoryRequirements(
VkImage hImage,
VkMemoryRequirements& memReq,
bool& dedicatedAllocation) const;
// Main allocation function.
VkResult AllocateMemory(
const VkMemoryRequirements& vkMemReq,
bool dedicatedAllocation,
const VmaAllocationCreateInfo& createInfo,
VmaSuballocationType suballocType,
VmaAllocation* pAllocation);
@ -3549,13 +3590,14 @@ private:
VkResult AllocateMemoryOfType(
const VkMemoryRequirements& vkMemReq,
bool dedicatedAllocation,
const VmaAllocationCreateInfo& createInfo,
uint32_t memTypeIndex,
VmaSuballocationType suballocType,
VmaAllocation* pAllocation);
// Allocates and registers new VkDeviceMemory specifically for single allocation.
VkResult AllocateOwnMemory(
VkResult AllocateDedicatedMemory(
VkDeviceSize size,
VmaSuballocationType suballocType,
uint32_t memTypeIndex,
@ -3563,8 +3605,8 @@ private:
void* pUserData,
VmaAllocation* pAllocation);
// Tries to free pMemory as Own Memory. Returns true if found and freed.
void FreeOwnMemory(VmaAllocation allocation);
// Tries to free pMemory as Dedicated Memory. Returns true if found and freed.
void FreeDedicatedMemory(VmaAllocation allocation);
};
////////////////////////////////////////////////////////////////////////////////
@ -3952,7 +3994,7 @@ VkDeviceSize VmaAllocation_T::GetOffset() const
{
case ALLOCATION_TYPE_BLOCK:
return m_BlockAllocation.m_Offset;
case ALLOCATION_TYPE_OWN:
case ALLOCATION_TYPE_DEDICATED:
return 0;
default:
VMA_ASSERT(0);
@ -3966,8 +4008,8 @@ VkDeviceMemory VmaAllocation_T::GetMemory() const
{
case ALLOCATION_TYPE_BLOCK:
return m_BlockAllocation.m_Block->m_hMemory;
case ALLOCATION_TYPE_OWN:
return m_OwnAllocation.m_hMemory;
case ALLOCATION_TYPE_DEDICATED:
return m_DedicatedAllocation.m_hMemory;
default:
VMA_ASSERT(0);
return VK_NULL_HANDLE;
@ -3980,8 +4022,8 @@ uint32_t VmaAllocation_T::GetMemoryTypeIndex() const
{
case ALLOCATION_TYPE_BLOCK:
return m_BlockAllocation.m_Block->m_MemoryTypeIndex;
case ALLOCATION_TYPE_OWN:
return m_OwnAllocation.m_MemoryTypeIndex;
case ALLOCATION_TYPE_DEDICATED:
return m_DedicatedAllocation.m_MemoryTypeIndex;
default:
VMA_ASSERT(0);
return UINT32_MAX;
@ -3994,8 +4036,8 @@ VMA_BLOCK_VECTOR_TYPE VmaAllocation_T::GetBlockVectorType() const
{
case ALLOCATION_TYPE_BLOCK:
return m_BlockAllocation.m_Block->m_BlockVectorType;
case ALLOCATION_TYPE_OWN:
return (m_OwnAllocation.m_PersistentMap ? VMA_BLOCK_VECTOR_TYPE_MAPPED : VMA_BLOCK_VECTOR_TYPE_UNMAPPED);
case ALLOCATION_TYPE_DEDICATED:
return (m_DedicatedAllocation.m_PersistentMap ? VMA_BLOCK_VECTOR_TYPE_MAPPED : VMA_BLOCK_VECTOR_TYPE_UNMAPPED);
default:
VMA_ASSERT(0);
return VMA_BLOCK_VECTOR_TYPE_COUNT;
@ -4016,8 +4058,8 @@ void* VmaAllocation_T::GetMappedData() const
return VMA_NULL;
}
break;
case ALLOCATION_TYPE_OWN:
return m_OwnAllocation.m_pMappedData;
case ALLOCATION_TYPE_DEDICATED:
return m_DedicatedAllocation.m_pMappedData;
default:
VMA_ASSERT(0);
return VMA_NULL;
@ -4030,7 +4072,7 @@ bool VmaAllocation_T::CanBecomeLost() const
{
case ALLOCATION_TYPE_BLOCK:
return m_BlockAllocation.m_CanBecomeLost;
case ALLOCATION_TYPE_OWN:
case ALLOCATION_TYPE_DEDICATED:
return false;
default:
VMA_ASSERT(0);
@ -4044,29 +4086,29 @@ VmaPool VmaAllocation_T::GetPool() const
return m_BlockAllocation.m_hPool;
}
VkResult VmaAllocation_T::OwnAllocMapPersistentlyMappedMemory(VmaAllocator hAllocator)
VkResult VmaAllocation_T::DedicatedAllocMapPersistentlyMappedMemory(VmaAllocator hAllocator)
{
VMA_ASSERT(m_Type == ALLOCATION_TYPE_OWN);
if(m_OwnAllocation.m_PersistentMap)
VMA_ASSERT(m_Type == ALLOCATION_TYPE_DEDICATED);
if(m_DedicatedAllocation.m_PersistentMap)
{
return (*hAllocator->GetVulkanFunctions().vkMapMemory)(
hAllocator->m_hDevice,
m_OwnAllocation.m_hMemory,
m_DedicatedAllocation.m_hMemory,
0,
VK_WHOLE_SIZE,
0,
&m_OwnAllocation.m_pMappedData);
&m_DedicatedAllocation.m_pMappedData);
}
return VK_SUCCESS;
}
void VmaAllocation_T::OwnAllocUnmapPersistentlyMappedMemory(VmaAllocator hAllocator)
void VmaAllocation_T::DedicatedAllocUnmapPersistentlyMappedMemory(VmaAllocator hAllocator)
{
VMA_ASSERT(m_Type == ALLOCATION_TYPE_OWN);
if(m_OwnAllocation.m_pMappedData)
VMA_ASSERT(m_Type == ALLOCATION_TYPE_DEDICATED);
if(m_DedicatedAllocation.m_pMappedData)
{
VMA_ASSERT(m_OwnAllocation.m_PersistentMap);
(*hAllocator->GetVulkanFunctions().vkUnmapMemory)(hAllocator->m_hDevice, m_OwnAllocation.m_hMemory);
m_OwnAllocation.m_pMappedData = VMA_NULL;
VMA_ASSERT(m_DedicatedAllocation.m_PersistentMap);
(*hAllocator->GetVulkanFunctions().vkUnmapMemory)(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory);
m_DedicatedAllocation.m_pMappedData = VMA_NULL;
}
}
@ -6173,6 +6215,7 @@ bool VmaDefragmentator::MoveMakesSense(
VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
m_UseMutex((pCreateInfo->flags & VMA_ALLOCATOR_EXTERNALLY_SYNCHRONIZED_BIT) == 0),
m_UseKhrDedicatedAllocation((pCreateInfo->flags & VMA_ALLOCATOR_KHR_DEDICATED_ALLOCATION_BIT) != 0),
m_PhysicalDevice(pCreateInfo->physicalDevice),
m_hDevice(pCreateInfo->device),
m_AllocationCallbacksSpecified(pCreateInfo->pAllocationCallbacks != VMA_NULL),
@ -6191,7 +6234,7 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
memset(&m_PhysicalDeviceProperties, 0, sizeof(m_PhysicalDeviceProperties));
memset(&m_pBlockVectors, 0, sizeof(m_pBlockVectors));
memset(&m_pOwnAllocations, 0, sizeof(m_pOwnAllocations));
memset(&m_pDedicatedAllocations, 0, sizeof(m_pDedicatedAllocations));
for(uint32_t i = 0; i < VK_MAX_MEMORY_HEAPS; ++i)
{
@ -6248,7 +6291,7 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
false); // isCustomPool
// No need to call m_pBlockVectors[memTypeIndex][blockVectorTypeIndex]->CreateMinBlocks here,
// becase minBlockCount is 0.
m_pOwnAllocations[memTypeIndex][blockVectorTypeIndex] = vma_new(this, AllocationVectorType)(VmaStlAllocator<VmaAllocation>(GetAllocationCallbacks()));
m_pDedicatedAllocations[memTypeIndex][blockVectorTypeIndex] = vma_new(this, AllocationVectorType)(VmaStlAllocator<VmaAllocation>(GetAllocationCallbacks()));
}
}
}
@ -6261,7 +6304,7 @@ VmaAllocator_T::~VmaAllocator_T()
{
for(size_t j = VMA_BLOCK_VECTOR_TYPE_COUNT; j--; )
{
vma_delete(this, m_pOwnAllocations[i][j]);
vma_delete(this, m_pDedicatedAllocations[i][j]);
vma_delete(this, m_pBlockVectors[i][j]);
}
}
@ -6284,13 +6327,35 @@ void VmaAllocator_T::ImportVulkanFunctions(const VmaVulkanFunctions* pVulkanFunc
m_VulkanFunctions.vkDestroyBuffer = &vkDestroyBuffer;
m_VulkanFunctions.vkCreateImage = &vkCreateImage;
m_VulkanFunctions.vkDestroyImage = &vkDestroyImage;
// Ignoring vkGetBufferMemoryRequirements2KHR.
// Ignoring vkGetImageMemoryRequirements2KHR.
#endif // #if VMA_STATIC_VULKAN_FUNCTIONS == 1
#define VMA_COPY_IF_NOT_NULL(funcName) \
if(pVulkanFunctions->funcName != VMA_NULL) m_VulkanFunctions.funcName = pVulkanFunctions->funcName;
if(pVulkanFunctions != VMA_NULL)
{
m_VulkanFunctions = *pVulkanFunctions;
VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceProperties);
VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties);
VMA_COPY_IF_NOT_NULL(vkAllocateMemory);
VMA_COPY_IF_NOT_NULL(vkFreeMemory);
VMA_COPY_IF_NOT_NULL(vkMapMemory);
VMA_COPY_IF_NOT_NULL(vkUnmapMemory);
VMA_COPY_IF_NOT_NULL(vkBindBufferMemory);
VMA_COPY_IF_NOT_NULL(vkBindImageMemory);
VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements);
VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements);
VMA_COPY_IF_NOT_NULL(vkCreateBuffer);
VMA_COPY_IF_NOT_NULL(vkDestroyBuffer);
VMA_COPY_IF_NOT_NULL(vkCreateImage);
VMA_COPY_IF_NOT_NULL(vkDestroyImage);
VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements2KHR);
VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements2KHR);
}
#undef VMA_COPY_IF_NOT_NULL
// If these asserts are hit, you must either #define VMA_STATIC_VULKAN_FUNCTIONS 1
// or pass valid pointers as VmaAllocatorCreateInfo::pVulkanFunctions.
VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceProperties != VMA_NULL);
@ -6307,6 +6372,11 @@ void VmaAllocator_T::ImportVulkanFunctions(const VmaVulkanFunctions* pVulkanFunc
VMA_ASSERT(m_VulkanFunctions.vkDestroyBuffer != VMA_NULL);
VMA_ASSERT(m_VulkanFunctions.vkCreateImage != VMA_NULL);
VMA_ASSERT(m_VulkanFunctions.vkDestroyImage != VMA_NULL);
if(m_UseKhrDedicatedAllocation)
{
VMA_ASSERT(m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR != VMA_NULL);
VMA_ASSERT(m_VulkanFunctions.vkGetImageMemoryRequirements2KHR != VMA_NULL);
}
}
VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex)
@ -6319,6 +6389,7 @@ VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex)
VkResult VmaAllocator_T::AllocateMemoryOfType(
const VkMemoryRequirements& vkMemReq,
bool dedicatedAllocation,
const VmaAllocationCreateInfo& createInfo,
uint32_t memTypeIndex,
VmaSuballocationType suballocType,
@ -6333,17 +6404,18 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
VmaAllocationCreateInfo finalCreateInfo = createInfo;
if(VMA_DEBUG_ALWAYS_OWN_MEMORY)
{
finalCreateInfo.flags |= VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT;
}
// Heuristics: Allocate own memory if requested size if greater than half of preferred block size.
const VkDeviceSize preferredBlockSize = blockVector->GetPreferredBlockSize();
if((finalCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0 &&
vkMemReq.size > preferredBlockSize / 2)
bool preferDedicatedMemory =
VMA_DEBUG_ALWAYS_DEDICATED_MEMORY ||
dedicatedAllocation ||
// Heuristics: Allocate dedicated memory if requested size if greater than half of preferred block size.
vkMemReq.size > preferredBlockSize / 2;
if(preferDedicatedMemory &&
(finalCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0 &&
finalCreateInfo.pool == VK_NULL_HANDLE)
{
finalCreateInfo.flags |= VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT;
finalCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
}
// If memory type is not HOST_VISIBLE, disable PERSISTENT_MAP.
@ -6353,7 +6425,7 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
finalCreateInfo.flags &= ~VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT;
}
if((finalCreateInfo.flags & VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT) != 0)
if((finalCreateInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0)
{
if((finalCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0)
{
@ -6361,7 +6433,7 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
}
else
{
return AllocateOwnMemory(
return AllocateDedicatedMemory(
vkMemReq.size,
suballocType,
memTypeIndex,
@ -6384,14 +6456,14 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
return res;
}
// 5. Try own memory.
// 5. Try dedicated memory.
if((finalCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0)
{
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}
else
{
res = AllocateOwnMemory(
res = AllocateDedicatedMemory(
vkMemReq.size,
suballocType,
memTypeIndex,
@ -6400,8 +6472,8 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
pAllocation);
if(res == VK_SUCCESS)
{
// Succeeded: AllocateOwnMemory function already filld pMemory, nothing more to do here.
VMA_DEBUG_LOG(" Allocated as OwnMemory");
// Succeeded: AllocateDedicatedMemory function already filld pMemory, nothing more to do here.
VMA_DEBUG_LOG(" Allocated as DedicatedMemory");
return VK_SUCCESS;
}
else
@ -6414,7 +6486,7 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
}
}
VkResult VmaAllocator_T::AllocateOwnMemory(
VkResult VmaAllocator_T::AllocateDedicatedMemory(
VkDeviceSize size,
VmaSuballocationType suballocType,
uint32_t memTypeIndex,
@ -6459,37 +6531,96 @@ VkResult VmaAllocator_T::AllocateOwnMemory(
}
*pAllocation = vma_new(this, VmaAllocation_T)(m_CurrentFrameIndex.load());
(*pAllocation)->InitOwnAllocation(memTypeIndex, hMemory, suballocType, map, pMappedData, size, pUserData);
(*pAllocation)->InitDedicatedAllocation(memTypeIndex, hMemory, suballocType, map, pMappedData, size, pUserData);
// Register it in m_pOwnAllocations.
// Register it in m_pDedicatedAllocations.
{
VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex], m_UseMutex);
AllocationVectorType* pOwnAllocations = m_pOwnAllocations[memTypeIndex][map ? VMA_BLOCK_VECTOR_TYPE_MAPPED : VMA_BLOCK_VECTOR_TYPE_UNMAPPED];
VMA_ASSERT(pOwnAllocations);
VmaVectorInsertSorted<VmaPointerLess>(*pOwnAllocations, *pAllocation);
VmaMutexLock lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);
AllocationVectorType* pDedicatedAllocations = m_pDedicatedAllocations[memTypeIndex][map ? VMA_BLOCK_VECTOR_TYPE_MAPPED : VMA_BLOCK_VECTOR_TYPE_UNMAPPED];
VMA_ASSERT(pDedicatedAllocations);
VmaVectorInsertSorted<VmaPointerLess>(*pDedicatedAllocations, *pAllocation);
}
VMA_DEBUG_LOG(" Allocated OwnMemory MemoryTypeIndex=#%u", memTypeIndex);
VMA_DEBUG_LOG(" Allocated DedicatedMemory MemoryTypeIndex=#%u", memTypeIndex);
return VK_SUCCESS;
}
void VmaAllocator_T::GetBufferMemoryRequirements(
VkBuffer hBuffer,
VkMemoryRequirements& memReq,
bool& dedicatedAllocation) const
{
if(m_UseKhrDedicatedAllocation)
{
VkBufferMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR };
memReqInfo.buffer = hBuffer;
VkMemoryDedicatedRequirementsKHR memDedicatedReq = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR };
VkMemoryRequirements2KHR memReq2 = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR };
memReq2.pNext = &memDedicatedReq;
(*m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR)(m_hDevice, &memReqInfo, &memReq2);
memReq = memReq2.memoryRequirements;
dedicatedAllocation =
(memDedicatedReq.requiresDedicatedAllocation != VK_FALSE) ||
(memDedicatedReq.prefersDedicatedAllocation != VK_FALSE);
}
else
{
(*m_VulkanFunctions.vkGetBufferMemoryRequirements)(m_hDevice, hBuffer, &memReq);
dedicatedAllocation = false;
}
}
void VmaAllocator_T::GetImageMemoryRequirements(
VkImage hImage,
VkMemoryRequirements& memReq,
bool& dedicatedAllocation) const
{
if(m_UseKhrDedicatedAllocation)
{
VkImageMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR };
memReqInfo.image = hImage;
VkMemoryDedicatedRequirementsKHR memDedicatedReq = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR };
VkMemoryRequirements2KHR memReq2 = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR };
memReq2.pNext = &memDedicatedReq;
(*m_VulkanFunctions.vkGetImageMemoryRequirements2KHR)(m_hDevice, &memReqInfo, &memReq2);
memReq = memReq2.memoryRequirements;
dedicatedAllocation =
(memDedicatedReq.requiresDedicatedAllocation != VK_FALSE) ||
(memDedicatedReq.prefersDedicatedAllocation != VK_FALSE);
}
else
{
(*m_VulkanFunctions.vkGetImageMemoryRequirements)(m_hDevice, hImage, &memReq);
dedicatedAllocation = false;
}
}
VkResult VmaAllocator_T::AllocateMemory(
const VkMemoryRequirements& vkMemReq,
bool dedicatedAllocation,
const VmaAllocationCreateInfo& createInfo,
VmaSuballocationType suballocType,
VmaAllocation* pAllocation)
{
if((createInfo.flags & VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT) != 0 &&
if((createInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0 &&
(createInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0)
{
VMA_ASSERT(0 && "Specifying VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT together with VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT makes no sense.");
VMA_ASSERT(0 && "Specifying VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT together with VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT makes no sense.");
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}
if((createInfo.pool != VK_NULL_HANDLE) &&
((createInfo.flags & (VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT)) != 0))
((createInfo.flags & (VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT)) != 0))
{
VMA_ASSERT(0 && "Specifying VMA_ALLOCATION_CREATE_OWN_MEMORY_BIT when pool != null is invalid.");
VMA_ASSERT(0 && "Specifying VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT when pool != null is invalid.");
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}
@ -6511,7 +6642,7 @@ VkResult VmaAllocator_T::AllocateMemory(
VkResult res = vmaFindMemoryTypeIndex(this, memoryTypeBits, &createInfo, &memTypeIndex);
if(res == VK_SUCCESS)
{
res = AllocateMemoryOfType(vkMemReq, createInfo, memTypeIndex, suballocType, pAllocation);
res = AllocateMemoryOfType(vkMemReq, dedicatedAllocation, createInfo, memTypeIndex, suballocType, pAllocation);
// Succeeded on first try.
if(res == VK_SUCCESS)
{
@ -6528,7 +6659,7 @@ VkResult VmaAllocator_T::AllocateMemory(
res = vmaFindMemoryTypeIndex(this, memoryTypeBits, &createInfo, &memTypeIndex);
if(res == VK_SUCCESS)
{
res = AllocateMemoryOfType(vkMemReq, createInfo, memTypeIndex, suballocType, pAllocation);
res = AllocateMemoryOfType(vkMemReq, dedicatedAllocation, createInfo, memTypeIndex, suballocType, pAllocation);
// Allocation from this alternative memory type succeeded.
if(res == VK_SUCCESS)
{
@ -6577,8 +6708,8 @@ void VmaAllocator_T::FreeMemory(const VmaAllocation allocation)
pBlockVector->Free(allocation);
}
break;
case VmaAllocation_T::ALLOCATION_TYPE_OWN:
FreeOwnMemory(allocation);
case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
FreeDedicatedMemory(allocation);
break;
default:
VMA_ASSERT(0);
@ -6618,19 +6749,19 @@ void VmaAllocator_T::CalculateStats(VmaStats* pStats)
}
}
// Process own allocations.
// Process dedicated allocations.
for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
{
const uint32_t memHeapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex);
VmaMutexLock ownAllocationsLock(m_OwnAllocationsMutex[memTypeIndex], m_UseMutex);
VmaMutexLock dedicatedAllocationsLock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);
for(uint32_t blockVectorType = 0; blockVectorType < VMA_BLOCK_VECTOR_TYPE_COUNT; ++blockVectorType)
{
AllocationVectorType* const pOwnAllocVector = m_pOwnAllocations[memTypeIndex][blockVectorType];
VMA_ASSERT(pOwnAllocVector);
for(size_t allocIndex = 0, allocCount = pOwnAllocVector->size(); allocIndex < allocCount; ++allocIndex)
AllocationVectorType* const pDedicatedAllocVector = m_pDedicatedAllocations[memTypeIndex][blockVectorType];
VMA_ASSERT(pDedicatedAllocVector);
for(size_t allocIndex = 0, allocCount = pDedicatedAllocVector->size(); allocIndex < allocCount; ++allocIndex)
{
VmaStatInfo allocationStatInfo;
(*pOwnAllocVector)[allocIndex]->OwnAllocCalcStatsInfo(allocationStatInfo);
(*pDedicatedAllocVector)[allocIndex]->DedicatedAllocCalcStatsInfo(allocationStatInfo);
VmaAddStatInfo(pStats->total, allocationStatInfo);
VmaAddStatInfo(pStats->memoryType[memTypeIndex], allocationStatInfo);
VmaAddStatInfo(pStats->memoryHeap[memHeapIndex], allocationStatInfo);
@ -6660,14 +6791,14 @@ void VmaAllocator_T::UnmapPersistentlyMappedMemory()
if((memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0 &&
(memFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0)
{
// Process OwnAllocations.
// Process DedicatedAllocations.
{
VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex], m_UseMutex);
AllocationVectorType* pOwnAllocationsVector = m_pOwnAllocations[memTypeIndex][VMA_BLOCK_VECTOR_TYPE_MAPPED];
for(size_t ownAllocIndex = pOwnAllocationsVector->size(); ownAllocIndex--; )
VmaMutexLock lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);
AllocationVectorType* pDedicatedAllocationsVector = m_pDedicatedAllocations[memTypeIndex][VMA_BLOCK_VECTOR_TYPE_MAPPED];
for(size_t dedicatedAllocIndex = pDedicatedAllocationsVector->size(); dedicatedAllocIndex--; )
{
VmaAllocation hAlloc = (*pOwnAllocationsVector)[ownAllocIndex];
hAlloc->OwnAllocUnmapPersistentlyMappedMemory(this);
VmaAllocation hAlloc = (*pDedicatedAllocationsVector)[dedicatedAllocIndex];
hAlloc->DedicatedAllocUnmapPersistentlyMappedMemory(this);
}
}
@ -6714,14 +6845,14 @@ VkResult VmaAllocator_T::MapPersistentlyMappedMemory()
if((memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0 &&
(memFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0)
{
// Process OwnAllocations.
// Process DedicatedAllocations.
{
VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex], m_UseMutex);
AllocationVectorType* pAllocationsVector = m_pOwnAllocations[memTypeIndex][VMA_BLOCK_VECTOR_TYPE_MAPPED];
for(size_t ownAllocIndex = 0, ownAllocCount = pAllocationsVector->size(); ownAllocIndex < ownAllocCount; ++ownAllocIndex)
VmaMutexLock lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);
AllocationVectorType* pAllocationsVector = m_pDedicatedAllocations[memTypeIndex][VMA_BLOCK_VECTOR_TYPE_MAPPED];
for(size_t dedicatedAllocIndex = 0, dedicatedAllocCount = pAllocationsVector->size(); dedicatedAllocIndex < dedicatedAllocCount; ++dedicatedAllocIndex)
{
VmaAllocation hAlloc = (*pAllocationsVector)[ownAllocIndex];
hAlloc->OwnAllocMapPersistentlyMappedMemory(this);
VmaAllocation hAlloc = (*pAllocationsVector)[dedicatedAllocIndex];
hAlloc->DedicatedAllocMapPersistentlyMappedMemory(this);
}
}
@ -6777,7 +6908,7 @@ VkResult VmaAllocator_T::Defragment(
VmaAllocation hAlloc = pAllocations[allocIndex];
VMA_ASSERT(hAlloc);
const uint32_t memTypeIndex = hAlloc->GetMemoryTypeIndex();
// OwnAlloc cannot be defragmented.
// DedicatedAlloc cannot be defragmented.
if((hAlloc->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK) &&
// Only HOST_VISIBLE memory types can be defragmented.
((m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) &&
@ -7045,16 +7176,16 @@ void VmaAllocator_T::FreeVulkanMemory(uint32_t memoryType, VkDeviceSize size, Vk
}
}
void VmaAllocator_T::FreeOwnMemory(VmaAllocation allocation)
void VmaAllocator_T::FreeDedicatedMemory(VmaAllocation allocation)
{
VMA_ASSERT(allocation && allocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_OWN);
VMA_ASSERT(allocation && allocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED);
const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
{
VmaMutexLock lock(m_OwnAllocationsMutex[memTypeIndex], m_UseMutex);
AllocationVectorType* const pOwnAllocations = m_pOwnAllocations[memTypeIndex][allocation->GetBlockVectorType()];
VMA_ASSERT(pOwnAllocations);
bool success = VmaVectorRemoveSorted<VmaPointerLess>(*pOwnAllocations, allocation);
VmaMutexLock lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);
AllocationVectorType* const pDedicatedAllocations = m_pDedicatedAllocations[memTypeIndex][allocation->GetBlockVectorType()];
VMA_ASSERT(pDedicatedAllocations);
bool success = VmaVectorRemoveSorted<VmaPointerLess>(*pDedicatedAllocations, allocation);
VMA_ASSERT(success);
}
@ -7067,27 +7198,27 @@ void VmaAllocator_T::FreeOwnMemory(VmaAllocation allocation)
FreeVulkanMemory(memTypeIndex, allocation->GetSize(), hMemory);
VMA_DEBUG_LOG(" Freed OwnMemory MemoryTypeIndex=%u", memTypeIndex);
VMA_DEBUG_LOG(" Freed DedicatedMemory MemoryTypeIndex=%u", memTypeIndex);
}
#if VMA_STATS_STRING_ENABLED
void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json)
{
bool ownAllocationsStarted = false;
bool dedicatedAllocationsStarted = false;
for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
{
VmaMutexLock ownAllocationsLock(m_OwnAllocationsMutex[memTypeIndex], m_UseMutex);
VmaMutexLock dedicatedAllocationsLock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex);
for(uint32_t blockVectorType = 0; blockVectorType < VMA_BLOCK_VECTOR_TYPE_COUNT; ++blockVectorType)
{
AllocationVectorType* const pOwnAllocVector = m_pOwnAllocations[memTypeIndex][blockVectorType];
VMA_ASSERT(pOwnAllocVector);
if(pOwnAllocVector->empty() == false)
AllocationVectorType* const pDedicatedAllocVector = m_pDedicatedAllocations[memTypeIndex][blockVectorType];
VMA_ASSERT(pDedicatedAllocVector);
if(pDedicatedAllocVector->empty() == false)
{
if(ownAllocationsStarted == false)
if(dedicatedAllocationsStarted == false)
{
ownAllocationsStarted = true;
json.WriteString("OwnAllocations");
dedicatedAllocationsStarted = true;
json.WriteString("DedicatedAllocations");
json.BeginObject();
}
@ -7101,9 +7232,9 @@ void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json)
json.BeginArray();
for(size_t i = 0; i < pOwnAllocVector->size(); ++i)
for(size_t i = 0; i < pDedicatedAllocVector->size(); ++i)
{
const VmaAllocation hAlloc = (*pOwnAllocVector)[i];
const VmaAllocation hAlloc = (*pDedicatedAllocVector)[i];
json.BeginObject(true);
json.WriteString("Size");
@ -7119,7 +7250,7 @@ void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json)
}
}
}
if(ownAllocationsStarted)
if(dedicatedAllocationsStarted)
{
json.EndObject();
}
@ -7185,10 +7316,12 @@ static VkResult AllocateMemoryForImage(
VMA_ASSERT(allocator && (image != VK_NULL_HANDLE) && pAllocationCreateInfo && pAllocation);
VkMemoryRequirements vkMemReq = {};
(*allocator->GetVulkanFunctions().vkGetImageMemoryRequirements)(allocator->m_hDevice, image, &vkMemReq);
bool dedicatedAllocation = false;
allocator->GetImageMemoryRequirements(image, vkMemReq, dedicatedAllocation);
return allocator->AllocateMemory(
vkMemReq,
dedicatedAllocation,
*pAllocationCreateInfo,
suballocType,
pAllocation);
@ -7531,6 +7664,7 @@ VkResult vmaAllocateMemory(
VkResult result = allocator->AllocateMemory(
*pVkMemoryRequirements,
false, // dedicatedAllocation
*pCreateInfo,
VMA_SUBALLOCATION_TYPE_UNKNOWN,
pAllocation);
@ -7557,10 +7691,12 @@ VkResult vmaAllocateMemoryForBuffer(
VMA_DEBUG_GLOBAL_MUTEX_LOCK
VkMemoryRequirements vkMemReq = {};
(*allocator->GetVulkanFunctions().vkGetBufferMemoryRequirements)(allocator->m_hDevice, buffer, &vkMemReq);
bool dedicatedAllocation = false;
allocator->GetBufferMemoryRequirements(buffer, vkMemReq, dedicatedAllocation);
VkResult result = allocator->AllocateMemory(
vkMemReq,
dedicatedAllocation,
*pCreateInfo,
VMA_SUBALLOCATION_TYPE_BUFFER,
pAllocation);
@ -7740,11 +7876,13 @@ VkResult vmaCreateBuffer(
{
// 2. vkGetBufferMemoryRequirements.
VkMemoryRequirements vkMemReq = {};
(*allocator->GetVulkanFunctions().vkGetBufferMemoryRequirements)(allocator->m_hDevice, *pBuffer, &vkMemReq);
bool dedicatedAllocation = false;
allocator->GetBufferMemoryRequirements(*pBuffer, vkMemReq, dedicatedAllocation);
// 3. Allocate memory using allocator.
res = allocator->AllocateMemory(
vkMemReq,
dedicatedAllocation,
*pAllocationCreateInfo,
VMA_SUBALLOCATION_TYPE_BUFFER,
pAllocation);