You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<divclass="textblock"><p>The library automatically creates and manages default memory pool for each memory type available on the device. A pool contains a number of <code>VkDeviceMemory</code> blocks. You can create custom pool and allocate memory out of it. It can be useful if you want to:</p>
69
+
<divclass="textblock"><p>A memory pool contains a number of <code>VkDeviceMemory</code> blocks. The library automatically creates and manages default pool for each memory type available on the device. Default memory pool automatically grows in size. Size of allocated blocks is also variable and managed automatically.</p>
70
+
<p>You can create custom pool and allocate memory out of it. It can be useful if you want to:</p>
70
71
<ul>
71
72
<li>Keep certain kind of allocations separate from others.</li>
72
-
<li>Enforce particular size of Vulkan memory blocks.</li>
73
+
<li>Enforce particular, fixed size of Vulkan memory blocks.</li>
73
74
<li>Limit maximum amount of Vulkan memory allocated for that pool.</li>
75
+
<li>Reserve minimum or fixed amount of Vulkan memory always preallocated for that pool.</li>
74
76
</ul>
75
77
<p>To use custom memory pools:</p>
76
78
<oltype="1">
@@ -79,7 +81,7 @@
79
81
<li>When making an allocation, set <aclass="el" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150" title="Pool that this allocation should be created in. ">VmaAllocationCreateInfo::pool</a> to this handle. You don't need to specify any other parameters of this structure, like usage.</li>
80
82
</ol>
81
83
<p>Example:</p>
82
-
<divclass="fragment"><divclass="line"><spanclass="comment">// Create a pool that could have at most 2 blocks, 128 MiB each.</span></div><divclass="line"><aclass="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a> poolCreateInfo = {};</div><divclass="line">poolCreateInfo.<aclass="code" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a> = ...</div><divclass="line">poolCreateInfo.blockSize = 128ull * 1024 * 1024;</div><divclass="line">poolCreateInfo.<aclass="code" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">maxBlockCount</a> = 2;</div><divclass="line"></div><divclass="line">VmaPool pool;</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a>(allocator, &poolCreateInfo, &pool);</div><divclass="line"></div><divclass="line"><spanclass="comment">// Allocate a buffer out of it.</span></div><divclass="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><divclass="line">bufCreateInfo.size = 1024;</div><divclass="line">bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><divclass="line"></div><divclass="line"><aclass="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><divclass="line">allocCreateInfo.<aclass="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> = pool;</div><divclass="line"></div><divclass="line">VkBuffer buf;</div><divclass="line">VmaAllocation alloc;</div><divclass="line"><aclass="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);</div></div><!-- fragment --><p>You have to free all allocations made from this pool before destroying it.</p>
84
+
<divclass="fragment"><divclass="line"><spanclass="comment">// Create a pool that can have at most 2 blocks, 128 MiB each.</span></div><divclass="line"><aclass="code" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a> poolCreateInfo = {};</div><divclass="line">poolCreateInfo.<aclass="code" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a> = ...</div><divclass="line">poolCreateInfo.blockSize = 128ull * 1024 * 1024;</div><divclass="line">poolCreateInfo.<aclass="code" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">maxBlockCount</a> = 2;</div><divclass="line"></div><divclass="line">VmaPool pool;</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a>(allocator, &poolCreateInfo, &pool);</div><divclass="line"></div><divclass="line"><spanclass="comment">// Allocate a buffer out of it.</span></div><divclass="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><divclass="line">bufCreateInfo.size = 1024;</div><divclass="line">bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><divclass="line"></div><divclass="line"><aclass="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><divclass="line">allocCreateInfo.<aclass="code" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> = pool;</div><divclass="line"></div><divclass="line">VkBuffer buf;</div><divclass="line">VmaAllocation alloc;</div><divclass="line"><aclass="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);</div></div><!-- fragment --><p>You have to free all allocations made from this pool before destroying it.</p>
83
85
<divclass="fragment"><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a>(allocator, buf, alloc);</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a5485779c8f1948238fc4e92232fa65e1">vmaDestroyPool</a>(allocator, pool);</div></div><!-- fragment --><h1><aclass="anchor" id="custom_memory_pools_MemTypeIndex"></a>
84
86
Choosing memory type index</h1>
85
87
<p>When creating a pool, you must explicitly specify memory type index. To find the one suitable for your buffers or images, you can use code similar to the following:</p>
<p>Memory in Vulkan doesn't need to be unmapped before using it on GPU, but unless a memory types has <code>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</code> flag set, you need to manually invalidate cache before reading of mapped pointer using function <code>vkvkInvalidateMappedMemoryRanges()</code> and flush cache after writing to mapped pointer using function <code>vkFlushMappedMemoryRanges()</code>. Example:</p>
84
84
<divclass="fragment"><divclass="line">memcpy(allocInfo.<aclass="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>, &constantBufferData, <spanclass="keyword">sizeof</span>(constantBufferData));</div><divclass="line"></div><divclass="line">VkMemoryPropertyFlags memFlags;</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a>(allocator, allocInfo.<aclass="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a>, &memFlags);</div><divclass="line"><spanclass="keywordflow">if</span>((memFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)</div><divclass="line">{</div><divclass="line"> VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };</div><divclass="line"> memRange.memory = allocInfo.<aclass="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a>;</div><divclass="line"> memRange.offset = allocInfo.<aclass="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a>;</div><divclass="line"> memRange.size = allocInfo.<aclass="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a>;</div><divclass="line"> vkFlushMappedMemoryRanges(device, 1, &memRange);</div><divclass="line">}</div></div><!-- fragment --><p>Please note that memory allocated with <code>VMA_MEMORY_USAGE_CPU_ONLY</code> is guaranteed to be host coherent.</p>
85
-
<p>Also, Windows drivers from all 3 PC GPU vendors (AMD, Intel, NVIDIA) currently provide <code>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</code> flag on all memory types that are <code>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</code>, so on this platform you may not need to bother. </p>
86
-
</div></div><!-- contents -->
85
+
<p>Also, Windows drivers from all 3 PC GPU vendors (AMD, Intel, NVIDIA) currently provide <code>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</code> flag on all memory types that are <code>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</code>, so on this platform you may not need to bother.</p>
<p>It may happen that your allocation ends up in memory that is <code>HOST_VISIBLE</code> (available for mapping) despite it wasn't explicitly requested. For example, application may work on integrated graphics with unified memory (like Intel) or allocation from video memory might have failed, so the library chose system memory as fallback.</p>
89
+
<p>You can detect this case and map such allocation to access its memory on CPU directly, instead of launching a transfer operation. You can even use <code>VMA_ALLOCATION_CREATE_MAPPED_BIT</code> flag while creating allocations that are not necessarily <code>HOST_VISIBLE</code> (e.g. using <code>VMA_MEMORY_USAGE_GPU_ONLY</code>). If the allocation ends up in memory type that is <code>HOST_VISIBLE</code>, it will be persistently mapped and you can use it directly. If not, the flag is just ignored. Example:</p>
90
+
<divclass="fragment"><divclass="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><divclass="line">bufCreateInfo.size = <spanclass="keyword">sizeof</span>(ConstantBuffer);</div><divclass="line">bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><divclass="line"></div><divclass="line"><aclass="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><divclass="line">allocCreateInfo.<aclass="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <aclass="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>;</div><divclass="line">allocCreateInfo.<aclass="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = <aclass="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>;</div><divclass="line"></div><divclass="line">VkBuffer buf;</div><divclass="line">VmaAllocation alloc;</div><divclass="line"><aclass="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);</div><divclass="line"></div><divclass="line"><spanclass="keywordflow">if</span>(allocInfo.<aclass="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a> != <spanclass="keyword">nullptr</span>)</div><divclass="line">{</div><divclass="line"><spanclass="comment">// Allocation ended up in mappable memory.</span></div><divclass="line"><spanclass="comment">// It's persistently mapped. You can access it directly.</span></div><divclass="line"> memcpy(allocInfo.<aclass="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>, &constantBufferData, <spanclass="keyword">sizeof</span>(constantBufferData));</div><divclass="line">}</div><divclass="line"><spanclass="keywordflow">else</span></div><divclass="line">{</div><divclass="line"><spanclass="comment">// Allocation ended up in non-mappable memory.</span></div><divclass="line"><spanclass="comment">// You need to create CPU-side copy in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer.</span></div><divclass="line">}</div></div><!-- fragment --></div></div><!-- contents -->
87
91
<!-- start footer part -->
88
92
<hrclass="footer"/><addressclass="footer"><small>
89
93
Generated by  <ahref="http://www.doxygen.org/index.html">
<trclass="memdesc:add09658ac14fe290ace25470ddd6d41b"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Use <aclass="el" href="vk__mem__alloc_8h.html#abf6bf6748c7a9fe7ce5b7835c0f56af4" title="Flags to be passed as VmaAllocationCreateInfo::flags. ">VmaAllocationCreateFlagBits</a> enum. <ahref="#add09658ac14fe290ace25470ddd6d41b">More...</a><br/></td></tr>
<trclass="memdesc:accb8b06b1f677d858cb9af20705fa910"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Intended usage of memory. <ahref="#accb8b06b1f677d858cb9af20705fa910">More...</a><br/></td></tr>
<p>Use <aclass="el" href="vk__mem__alloc_8h.html#abf6bf6748c7a9fe7ce5b7835c0f56af4" title="Flags to be passed as VmaAllocationCreateInfo::flags. ">VmaAllocationCreateFlagBits</a> enum. </p>
0 commit comments