Many minor formatting tweaks in documentation.

This commit is contained in:
Adam Sawicki 2018-03-09 17:35:48 +01:00
parent a1bd730379
commit 359793763a
15 changed files with 211 additions and 210 deletions

View File

@ -74,7 +74,7 @@ Allocation user data</h1>
<p>Values of (non-zero) allocations' <code>pUserData</code> are printed in JSON report created by <a class="el" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0" title="Builds and returns statistics as string in JSON format. ">vmaBuildStatsString()</a>, in hexadecimal form.</p>
<h1><a class="anchor" id="allocation_names"></a>
Allocation names</h1>
<p>There is alternative mode available where <code>pUserData</code> pointer is used to point to a null-terminated string, giving a name to the allocation. To use this mode, set <code>VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</code> flag in <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a>. Then <code>pUserData</code> passed as <a class="el" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19" title="Custom general-purpose pointer that will be stored in VmaAllocation, can be read as VmaAllocationInfo...">VmaAllocationCreateInfo::pUserData</a> or argument to <a class="el" href="vk__mem__alloc_8h.html#af9147d31ffc11d62fc187bde283ed14f" title="Sets pUserData in given allocation to new value. ">vmaSetAllocationUserData()</a> must be either null or pointer to a null-terminated string. The library creates internal copy of the string, so the pointer you pass doesn't need to be valid for whole lifetime of the allocation. You can free it after the call.</p>
<p>There is alternative mode available where <code>pUserData</code> pointer is used to point to a null-terminated string, giving a name to the allocation. To use this mode, set <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a> flag in <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a>. Then <code>pUserData</code> passed as <a class="el" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19" title="Custom general-purpose pointer that will be stored in VmaAllocation, can be read as VmaAllocationInfo...">VmaAllocationCreateInfo::pUserData</a> or argument to <a class="el" href="vk__mem__alloc_8h.html#af9147d31ffc11d62fc187bde283ed14f" title="Sets pUserData in given allocation to new value. ">vmaSetAllocationUserData()</a> must be either null or pointer to a null-terminated string. The library creates internal copy of the string, so the pointer you pass doesn't need to be valid for whole lifetime of the allocation. You can free it after the call.</p>
<div class="fragment"><div class="line">VkImageCreateInfo imageInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };</div><div class="line"><span class="comment">// Fill imageInfo...</span></div><div class="line"></div><div class="line">std::string imageName = <span class="stringliteral">&quot;Texture: &quot;</span>;</div><div class="line">imageName += fileName;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>;</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a>;</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19">pUserData</a> = imageName.c_str();</div><div class="line"></div><div class="line">VkImage image;</div><div class="line">VmaAllocation allocation;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73">vmaCreateImage</a>(allocator, &amp;imageInfo, &amp;allocCreateInfo, &amp;image, &amp;allocation, <span class="keyword">nullptr</span>);</div></div><!-- fragment --><p>The value of <code>pUserData</code> pointer of the allocation will be different than the one you passed when setting allocation's name - pointing to a buffer managed internally that holds copy of the string.</p>
<div class="fragment"><div class="line"><a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b">vmaGetAllocationInfo</a>(allocator, allocation, &amp;allocInfo);</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span>* imageName = (<span class="keyword">const</span> <span class="keywordtype">char</span>*)allocInfo.<a class="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a>;</div><div class="line">printf(<span class="stringliteral">&quot;Image name: %s\n&quot;</span>, imageName);</div></div><!-- fragment --><p>That string is also printed in JSON report created by <a class="el" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0" title="Builds and returns statistics as string in JSON format. ">vmaBuildStatsString()</a>. </p>
</div></div><!-- contents -->

View File

@ -87,7 +87,7 @@ Required and preferred flags</h1>
<p>If you use <a class="el" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910" title="Intended usage of memory. ">VmaAllocationCreateInfo::usage</a>, it is just internally converted to a set of required and preferred flags.</p>
<h1><a class="anchor" id="choosing_memory_type_explicit_memory_types"></a>
Explicit memory types</h1>
<p>If you inspected memory types available on the physical device and you have a preference for memory types that you want to use, you can fill member <a class="el" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055" title="Bitmask containing one bit set for every memory type acceptable for this allocation. ">VmaAllocationCreateInfo::memoryTypeBits</a>. It is a bit mask, where each bit set means that a memory type with that index is allowed to be used for the allocation. Special value 0, just like UINT32_MAX, means there are no restrictions to memory type index.</p>
<p>If you inspected memory types available on the physical device and you have a preference for memory types that you want to use, you can fill member <a class="el" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055" title="Bitmask containing one bit set for every memory type acceptable for this allocation. ">VmaAllocationCreateInfo::memoryTypeBits</a>. It is a bit mask, where each bit set means that a memory type with that index is allowed to be used for the allocation. Special value 0, just like <code>UINT32_MAX</code>, means there are no restrictions to memory type index.</p>
<p>Please note that this member is NOT just a memory type index. Still you can use it to choose just one, specific memory type. For example, if you already determined that your buffer should be created in memory type 2, use following code:</p>
<div class="fragment"><div class="line">uint32_t memoryTypeIndex = 2;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocInfo = {};</div><div class="line">allocInfo.<a class="code" href="struct_vma_allocation_create_info.html#a3bf940c0271d85d6ba32a4d820075055">memoryTypeBits</a> = 1u &lt;&lt; memoryTypeIndex;</div><div class="line"></div><div class="line">VkBuffer buffer;</div><div class="line">VmaAllocation allocation;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufferInfo, &amp;allocInfo, &amp;buffer, &amp;allocation, <span class="keyword">nullptr</span>);</div></div><!-- fragment --><h1><a class="anchor" id="choosing_memory_type_custom_memory_pools"></a>
Custom memory pools</h1>

View File

@ -76,13 +76,13 @@ Pointers to Vulkan functions</h1>
</ol>
<h1><a class="anchor" id="custom_memory_allocator"></a>
Custom host memory allocator</h1>
<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>
<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. Optional. ">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>
<h1><a class="anchor" id="allocation_callbacks"></a>
Device memory allocation callbacks</h1>
<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>
<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. Optional. ">VmaAllocatorCreateInfo::pDeviceMemoryCallbacks</a>.</p>
<h1><a class="anchor" id="heap_memory_limit"></a>
Device heap memory limit</h1>
<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>
<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>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>

View File

@ -67,14 +67,14 @@ $(function() {
</div><!--header-->
<div class="contents">
<div class="textblock"><p>If your game oversubscribes video memory, if may work OK in previous-generation graphics APIs (DirectX 9, 10, 11, OpenGL) because resources are automatically paged to system RAM. In Vulkan you can't do it because when you run out of memory, an allocation just fails. If you have more data (e.g. textures) that can fit into VRAM and you don't need it all at once, you may want to upload them to GPU on demand and "push out" ones that are not used for a long time to make room for the new ones, effectively using VRAM (or a cartain memory pool) as a form of cache. Vulkan Memory Allocator can help you with that by supporting a concept of "lost allocations".</p>
<p>To create an allocation that can become lost, include <code>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</code> flag in <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a>. Before using a buffer or image bound to such allocation in every new frame, you need to query it if it's not lost. To check it: call <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> and see if <a class="el" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67" title="Handle to Vulkan memory object. ">VmaAllocationInfo::deviceMemory</a> is not <code>VK_NULL_HANDLE</code>. If the allocation is lost, you should not use it or buffer/image bound to it. You mustn't forget to destroy this allocation and this buffer/image.</p>
<p>To create an allocation that can make some other allocations lost to make room for it, use <code>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</code> flag. You will usually use both flags <code>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</code> and <code>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</code> at the same time.</p>
<p>Warning! Current implementation uses quite naive, brute force algorithm, which can make allocation calls that use <code>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</code> flag quite slow. A new, more optimal algorithm and data structure to speed this up is planned for the future.</p>
<p><b>When interleaving creation of new allocations with usage of existing ones, how do you make sure that an allocation won't become lost while it's used in the current frame?</b></p>
<p>To create an allocation that can become lost, include <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> flag in <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a>. Before using a buffer or image bound to such allocation in every new frame, you need to query it if it's not lost. To check it: call <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> and see if <a class="el" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67" title="Handle to Vulkan memory object. ">VmaAllocationInfo::deviceMemory</a> is not <code>VK_NULL_HANDLE</code>. If the allocation is lost, you should not use it or buffer/image bound to it. You mustn't forget to destroy this allocation and this buffer/image.</p>
<p>To create an allocation that can make some other allocations lost to make room for it, use <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a> flag. You will usually use both flags <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a> and <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> at the same time.</p>
<p>Warning! Current implementation uses quite naive, brute force algorithm, which can make allocation calls that use <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a> flag quite slow. A new, more optimal algorithm and data structure to speed this up is planned for the future.</p>
<p><b>Q: When interleaving creation of new allocations with usage of existing ones, how do you make sure that an allocation won't become lost while it's used in the current frame?</b></p>
<p>It is ensured because <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> not only returns allocation parameters and checks whether it's not lost, but when it's not, it also atomically marks it as used in the current frame, which makes it impossible to become lost in that frame. It uses lockless algorithm, so it works fast and doesn't involve locking any internal mutex.</p>
<p><b>What if my allocation may still be in use by the GPU when it's rendering a previous frame while I already submit new frame on the CPU?</b></p>
<p><b>Q: What if my allocation may still be in use by the GPU when it's rendering a previous frame while I already submit new frame on the CPU?</b></p>
<p>You can make sure that allocations "touched" by <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> will not become lost for a number of additional frames back from the current one by specifying this number as <a class="el" href="struct_vma_allocator_create_info.html#a21ea188dd212b8171cb9ecbed4a2a3a7" title="Maximum number of additional frames that are in use at the same time as current frame. ">VmaAllocatorCreateInfo::frameInUseCount</a> (for default memory pool) and <a class="el" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa" title="Maximum number of additional frames that are in use at the same time as current frame. ">VmaPoolCreateInfo::frameInUseCount</a> (for custom pool).</p>
<p><b>How do you inform the library when new frame starts?</b></p>
<p><b>Q: How do you inform the library when new frame starts?</b></p>
<p>You need to call function <a class="el" href="vk__mem__alloc_8h.html#ade56bf8dc9f5a5eaddf5f119ed525236" title="Sets index of the current frame. ">vmaSetCurrentFrameIndex()</a>.</p>
<p>Example code:</p>
<div class="fragment"><div class="line"><span class="keyword">struct </span>MyBuffer</div><div class="line">{</div><div class="line"> VkBuffer m_Buf = <span class="keyword">nullptr</span>;</div><div class="line"> VmaAllocation m_Alloc = <span class="keyword">nullptr</span>;</div><div class="line"></div><div class="line"> <span class="comment">// Called when the buffer is really needed in the current frame.</span></div><div class="line"> <span class="keywordtype">void</span> EnsureBuffer();</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keywordtype">void</span> MyBuffer::EnsureBuffer()</div><div class="line">{</div><div class="line"> <span class="comment">// Buffer has been created.</span></div><div class="line"> <span class="keywordflow">if</span>(m_Buf != VK_NULL_HANDLE)</div><div class="line"> {</div><div class="line"> <span class="comment">// Check if its allocation is not lost + mark it as used in current frame.</span></div><div class="line"> <a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><div class="line"> <a class="code" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b">vmaGetAllocationInfo</a>(allocator, m_Alloc, &amp;allocInfo);</div><div class="line"> <span class="keywordflow">if</span>(allocInfo.<a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a> != VK_NULL_HANDLE)</div><div class="line"> {</div><div class="line"> <span class="comment">// It&#39;s all OK - safe to use m_Buf.</span></div><div class="line"> <span class="keywordflow">return</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Buffer not yet exists or lost - destroy and recreate it.</span></div><div class="line"></div><div class="line"> <a class="code" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a>(allocator, m_Buf, m_Alloc);</div><div class="line"></div><div class="line"> VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line"> bufCreateInfo.size = 1024;</div><div class="line"> bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><div class="line"></div><div class="line"> <a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line"> allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>;</div><div class="line"> allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> |</div><div class="line"> <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a>;</div><div class="line"></div><div class="line"> <a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;m_Buf, &amp;m_Alloc, <span class="keyword">nullptr</span>);</div><div class="line">}</div></div><!-- fragment --><p>When using lost allocations, you may see some Vulkan validation layer warnings about overlapping regions of memory bound to different kinds of buffers and images. This is still valid as long as you implement proper handling of lost allocations (like in the example above) and don't use them.</p>
@ -83,8 +83,8 @@ $(function() {
<li>Try to find free range of memory in existing blocks.</li>
<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_DEDICATED_MEMORY_BIT</code>.</li>
<li>If failed and <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a> 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 <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f" title="Set this flag if the allocation should have its own memory block. ">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a>.</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

@ -72,23 +72,23 @@ Mapping functions</h1>
<p>The library provides following functions for mapping of a specific <code>VmaAllocation</code>: <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a>, <a class="el" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45" title="Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). ">vmaUnmapMemory()</a>. They are safer and more convenient to use than standard Vulkan functions. You can map an allocation multiple times simultaneously - mapping is reference-counted internally. You can also map different allocations simultaneously regardless of whether they use the same <code>VkDeviceMemory</code> block. They way it's implemented is that the library always maps entire memory block, not just region of the allocation. For further details, see description of <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a> function. Example:</p>
<div class="fragment"><div class="line"><span class="comment">// Having these objects initialized:</span></div><div class="line"></div><div class="line"><span class="keyword">struct </span>ConstantBuffer</div><div class="line">{</div><div class="line"> ...</div><div class="line">};</div><div class="line">ConstantBuffer constantBufferData;</div><div class="line"></div><div class="line">VmaAllocator allocator;</div><div class="line">VmaBuffer constantBuffer;</div><div class="line">VmaAllocation constantBufferAllocation;</div><div class="line"></div><div class="line"><span class="comment">// You can map and fill your buffer using following code:</span></div><div class="line"></div><div class="line"><span class="keywordtype">void</span>* mappedData;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069">vmaMapMemory</a>(allocator, constantBufferAllocation, &amp;mappedData);</div><div class="line">memcpy(mappedData, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a>(allocator, constantBufferAllocation);</div></div><!-- fragment --><h1><a class="anchor" id="memory_mapping_persistently_mapped_memory"></a>
Persistently mapped memory</h1>
<p>Kepping your memory persistently mapped is generally OK in Vulkan. You don't need to unmap it before using its data on the GPU. The library provides a special feature designed for that: Allocations made with <code>VMA_ALLOCATION_CREATE_MAPPED_BIT</code> flag set in <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a> stay mapped all the time, so you can just access CPU pointer to it any time without a need to call any "map" or "unmap" function. Example:</p>
<p>Kepping your memory persistently mapped is generally OK in Vulkan. You don't need to unmap it before using its data on the GPU. The library provides a special feature designed for that: Allocations made with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> flag set in <a class="el" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b" title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a> stay mapped all the time, so you can just access CPU pointer to it any time without a need to call any "map" or "unmap" function. Example:</p>
<div class="fragment"><div class="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line">bufCreateInfo.size = <span class="keyword">sizeof</span>(ConstantBuffer);</div><div class="line">bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a>;</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>;</div><div class="line"></div><div class="line">VkBuffer buf;</div><div class="line">VmaAllocation alloc;</div><div class="line"><a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, &amp;allocInfo);</div><div class="line"></div><div class="line"><span class="comment">// Buffer is already mapped. You can access its memory.</span></div><div class="line">memcpy(allocInfo.<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div></div><!-- fragment --><p>There are some exceptions though, when you should consider mapping memory only for a short period of time:</p>
<ul>
<li>When operating system is Windows 7 or 8.x (Windows 10 is not affected because it uses WDDM2), device is discrete AMD GPU, and memory type is the special 256 MiB pool of <code>DEVICE_LOCAL + HOST_VISIBLE</code> memory (selected when you use <code>VMA_MEMORY_USAGE_CPU_TO_GPU</code>), then whenever a memory block allocated from this memory type stays mapped for the time of any call to <code>vkQueueSubmit()</code> or <code>vkQueuePresentKHR()</code>, this block is migrated by WDDM to system RAM, which degrades performance. It doesn't matter if that particular memory block is actually used by the command buffer being submitted.</li>
<li>When operating system is Windows 7 or 8.x (Windows 10 is not affected because it uses WDDM2), device is discrete AMD GPU, and memory type is the special 256 MiB pool of <code>DEVICE_LOCAL + HOST_VISIBLE</code> memory (selected when you use <a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca9066b52c5a7079bb74a69aaf8b92ff67">VMA_MEMORY_USAGE_CPU_TO_GPU</a>), then whenever a memory block allocated from this memory type stays mapped for the time of any call to <code>vkQueueSubmit()</code> or <code>vkQueuePresentKHR()</code>, this block is migrated by WDDM to system RAM, which degrades performance. It doesn't matter if that particular memory block is actually used by the command buffer being submitted.</li>
<li>Keeping many large memory blocks mapped may impact performance or stability of some debugging tools.</li>
</ul>
<h1><a class="anchor" id="memory_mapping_cache_control"></a>
Cache control</h1>
<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>
<div class="fragment"><div class="line">memcpy(allocInfo.<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div><div class="line"></div><div class="line">VkMemoryPropertyFlags memFlags;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a>(allocator, allocInfo.<a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a>, &amp;memFlags);</div><div class="line"><span class="keywordflow">if</span>((memFlags &amp; VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)</div><div class="line">{</div><div class="line"> VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };</div><div class="line"> memRange.memory = allocInfo.<a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a>;</div><div class="line"> memRange.offset = allocInfo.<a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a>;</div><div class="line"> memRange.size = allocInfo.<a class="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a>;</div><div class="line"> vkFlushMappedMemoryRanges(device, 1, &amp;memRange);</div><div class="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>
<div class="fragment"><div class="line">memcpy(allocInfo.<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div><div class="line"></div><div class="line">VkMemoryPropertyFlags memFlags;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a>(allocator, allocInfo.<a class="code" href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a>, &amp;memFlags);</div><div class="line"><span class="keywordflow">if</span>((memFlags &amp; VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)</div><div class="line">{</div><div class="line"> VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };</div><div class="line"> memRange.memory = allocInfo.<a class="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a>;</div><div class="line"> memRange.offset = allocInfo.<a class="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a>;</div><div class="line"> memRange.size = allocInfo.<a class="code" href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a>;</div><div class="line"> vkFlushMappedMemoryRanges(device, 1, &amp;memRange);</div><div class="line">}</div></div><!-- fragment --><p>Please note that memory allocated with <a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a> is guaranteed to be host coherent.</p>
<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>
<h1><a class="anchor" id="memory_mapping_finding_if_memory_mappable"></a>
Finding out if memory is mappable</h1>
<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>
<p>You can detect this case and map such allocation to access its memory on CPU directly, instead of launching a transfer operation. In order to do that: inspect <code>allocInfo.memoryType</code>, call <a class="el" href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca" title="Given Memory Type Index, returns Property Flags of this memory type. ">vmaGetMemoryTypeProperties()</a>, and look for <code>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</code> flag in properties of that memory type.</p>
<p>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>
<div class="fragment"><div class="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line">bufCreateInfo.size = <span class="keyword">sizeof</span>(ConstantBuffer);</div><div class="line">bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>;</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>;</div><div class="line"></div><div class="line">VkBuffer buf;</div><div class="line">VmaAllocation alloc;</div><div class="line"><a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, &amp;allocInfo);</div><div class="line"></div><div class="line"><span class="keywordflow">if</span>(allocInfo.<a class="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a> != <span class="keyword">nullptr</span>)</div><div class="line">{</div><div class="line"> <span class="comment">// Allocation ended up in mappable memory.</span></div><div class="line"> <span class="comment">// It&#39;s persistently mapped. You can access it directly.</span></div><div class="line"> memcpy(allocInfo.<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div><div class="line">}</div><div class="line"><span class="keywordflow">else</span></div><div class="line">{</div><div class="line"> <span class="comment">// Allocation ended up in non-mappable memory.</span></div><div class="line"> <span class="comment">// You need to create CPU-side copy in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer.</span></div><div class="line">}</div></div><!-- fragment --> </div></div><!-- contents -->
<p>You can even use <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> flag while creating allocations that are not necessarily <code>HOST_VISIBLE</code> (e.g. using <a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>). 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>
<div class="fragment"><div class="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><div class="line">bufCreateInfo.size = <span class="keyword">sizeof</span>(ConstantBuffer);</div><div class="line">bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div><div class="line"></div><div class="line"><a class="code" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccac6b5dc1432d88647aa4cd456246eadf7">VMA_MEMORY_USAGE_GPU_ONLY</a>;</div><div class="line">allocCreateInfo.<a class="code" href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = <a class="code" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>;</div><div class="line"></div><div class="line">VkBuffer buf;</div><div class="line">VmaAllocation alloc;</div><div class="line"><a class="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, &amp;allocInfo);</div><div class="line"></div><div class="line"><span class="keywordflow">if</span>(allocInfo.<a class="code" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13">pUserData</a> != <span class="keyword">nullptr</span>)</div><div class="line">{</div><div class="line"> <span class="comment">// Allocation ended up in mappable memory.</span></div><div class="line"> <span class="comment">// It&#39;s persistently mapped. You can access it directly.</span></div><div class="line"> memcpy(allocInfo.<a class="code" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>, &amp;constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div><div class="line">}</div><div class="line"><span class="keywordflow">else</span></div><div class="line">{</div><div class="line"> <span class="comment">// Allocation ended up in non-mappable memory.</span></div><div class="line"> <span class="comment">// You need to create CPU-side buffer in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer.</span></div><div class="line">}</div></div><!-- fragment --> </div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">

View File

@ -175,7 +175,7 @@ If <code>pool</code> is not null, this member is ignored. </p>
</div><div class="memdoc">
<p>Custom general-purpose pointer that will be stored in VmaAllocation, can be read as <a class="el" href="struct_vma_allocation_info.html#adc507656149c04de7ed95d0042ba2a13" title="Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vma...">VmaAllocationInfo::pUserData</a> and changed using <a class="el" href="vk__mem__alloc_8h.html#af9147d31ffc11d62fc187bde283ed14f" title="Sets pUserData in given allocation to new value. ">vmaSetAllocationUserData()</a>. </p>
<p>If <code>VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</code> is used, it must be either null or pointer to a null-terminated string. The string will be then copied to internal buffer, so it doesn't need to be valid after allocation call. </p>
<p>If <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520">VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT</a> is used, it must be either null or pointer to a null-terminated string. The string will be then copied to internal buffer, so it doesn't need to be valid after allocation call. </p>
</div>
</div>
@ -210,7 +210,7 @@ If <code>pool</code> is not null, this member is ignored. </p>
</div><div class="memdoc">
<p>Intended usage of memory. </p>
<p>You can leave <code>VMA_MEMORY_USAGE_UNKNOWN</code> if you specify memory requirements in other way. <br />
<p>You can leave <a class="el" href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305ccaf50d27e34e0925cf3a63db8c839121dd">VMA_MEMORY_USAGE_UNKNOWN</a> if you specify memory requirements in other way. <br />
If <code>pool</code> is not null, this member is ignored. </p>
</div>

View File

@ -161,7 +161,7 @@ Public Attributes</h2></td></tr>
</div><div class="memdoc">
<p>Pointer to the beginning of this allocation as mapped data. </p>
<p>If the allocation hasn't been mapped using <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a> and hasn't been created with <code>VMA_ALLOCATION_CREATE_MAPPED_BIT</code> flag, this value null.</p>
<p>If the allocation hasn't been mapped using <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a> and hasn't been created with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> flag, this value null.</p>
<p>It can change after call to <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a>, <a class="el" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45" title="Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). ">vmaUnmapMemory()</a>. It can also change after call to <a class="el" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb" title="Compacts memory by moving allocations. ">vmaDefragment()</a> if this allocation is passed to the function. </p>
</div>

View File

@ -83,19 +83,19 @@ Public Attributes</h2></td></tr>
<tr class="memdesc:ad924ddd77b04039c88d0c09b0ffcd500"><td class="mdescLeft">&#160;</td><td class="mdescRight">Vulkan device. <a href="#ad924ddd77b04039c88d0c09b0ffcd500">More...</a><br /></td></tr>
<tr class="separator:ad924ddd77b04039c88d0c09b0ffcd500"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8e4714298e3121cdd8b214a1ae7a637a"><td class="memItemLeft" align="right" valign="top">VkDeviceSize&#160;</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">&#160;</td><td class="mdescRight">Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from large heaps &gt; 1 GiB. <a href="#a8e4714298e3121cdd8b214a1ae7a637a">More...</a><br /></td></tr>
<tr class="memdesc:a8e4714298e3121cdd8b214a1ae7a637a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from large heaps &gt; 1 GiB. Optional. <a href="#a8e4714298e3121cdd8b214a1ae7a637a">More...</a><br /></td></tr>
<tr class="separator:a8e4714298e3121cdd8b214a1ae7a637a"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a6e409087e3be55400d0e4ccbe43c608d"><td class="memItemLeft" align="right" valign="top">const VkAllocationCallbacks *&#160;</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">&#160;</td><td class="mdescRight">Custom CPU memory allocation callbacks. <a href="#a6e409087e3be55400d0e4ccbe43c608d">More...</a><br /></td></tr>
<tr class="memdesc:a6e409087e3be55400d0e4ccbe43c608d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Custom CPU memory allocation callbacks. Optional. <a href="#a6e409087e3be55400d0e4ccbe43c608d">More...</a><br /></td></tr>
<tr class="separator:a6e409087e3be55400d0e4ccbe43c608d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af1380969b5e1ea4c3184a877892d260e"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="struct_vma_device_memory_callbacks.html">VmaDeviceMemoryCallbacks</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e">pDeviceMemoryCallbacks</a></td></tr>
<tr class="memdesc:af1380969b5e1ea4c3184a877892d260e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Informative callbacks for vkAllocateMemory, vkFreeMemory. <a href="#af1380969b5e1ea4c3184a877892d260e">More...</a><br /></td></tr>
<tr class="memdesc:af1380969b5e1ea4c3184a877892d260e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Informative callbacks for <code>vkAllocateMemory</code>, <code>vkFreeMemory</code>. Optional. <a href="#af1380969b5e1ea4c3184a877892d260e">More...</a><br /></td></tr>
<tr class="separator:af1380969b5e1ea4c3184a877892d260e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a21ea188dd212b8171cb9ecbed4a2a3a7"><td class="memItemLeft" align="right" valign="top">uint32_t&#160;</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">&#160;</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">&#160;</td></tr>
<tr class="memitem:a31c192aa6cbffa33279f6d9f0c47c44b"><td class="memItemLeft" align="right" valign="top">const VkDeviceSize *&#160;</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">&#160;</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="memdesc:a31c192aa6cbffa33279f6d9f0c47c44b"><td class="mdescLeft">&#160;</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">&#160;</td></tr>
<tr class="memitem:a3dc197be3227da7338b1643f70db36bd"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="struct_vma_vulkan_functions.html">VmaVulkanFunctions</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_allocator_create_info.html#a3dc197be3227da7338b1643f70db36bd">pVulkanFunctions</a></td></tr>
<tr class="memdesc:a3dc197be3227da7338b1643f70db36bd"><td class="mdescLeft">&#160;</td><td class="mdescRight">Pointers to Vulkan functions. Can be null if you leave define <code>VMA_STATIC_VULKAN_FUNCTIONS 1</code>. <a href="#a3dc197be3227da7338b1643f70db36bd">More...</a><br /></td></tr>
@ -168,7 +168,7 @@ Public Attributes</h2></td></tr>
</table>
</div><div class="memdoc">
<p>Custom CPU memory allocation callbacks. </p>
<p>Custom CPU memory allocation callbacks. Optional. </p>
<p>Optional, can be null. When specified, will also be used for all CPU-side memory allocations. </p>
</div>
@ -185,7 +185,7 @@ Public Attributes</h2></td></tr>
</table>
</div><div class="memdoc">
<p>Informative callbacks for vkAllocateMemory, vkFreeMemory. </p>
<p>Informative callbacks for <code>vkAllocateMemory</code>, <code>vkFreeMemory</code>. Optional. </p>
<p>Optional, can be null. </p>
</div>
@ -202,7 +202,7 @@ Public Attributes</h2></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>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>
@ -243,7 +243,7 @@ Public Attributes</h2></td></tr>
</table>
</div><div class="memdoc">
<p>Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from large heaps &gt; 1 GiB. </p>
<p>Preferred size of a single <code>VkDeviceMemory</code> block to be allocated from large heaps &gt; 1 GiB. Optional. </p>
<p>Set to 0 to use default, which is currently 256 MiB. </p>
</div>

View File

@ -83,7 +83,7 @@ Public Attributes</h2></td></tr>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>Set of callbacks that the library will call for <code>vkAllocateMemory</code> and <code>vkFreeMemory</code>. </p>
<p>Provided for informative purpose, e.g. to gather statistics about number of allocations or total amount of memory allocated in Vulkan.</p>
<p>Used in <a class="el" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e" title="Informative callbacks for vkAllocateMemory, vkFreeMemory. ">VmaAllocatorCreateInfo::pDeviceMemoryCallbacks</a>. </p>
<p>Used in <a class="el" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e" title="Informative callbacks for vkAllocateMemory, vkFreeMemory. Optional. ">VmaAllocatorCreateInfo::pDeviceMemoryCallbacks</a>. </p>
</div><h2 class="groupheader">Member Data Documentation</h2>
<a id="a4f17f7b255101e733b44d5633aceabfb"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a4f17f7b255101e733b44d5633aceabfb">&#9670;&nbsp;</a></span>pfnAllocate</h2>

View File

@ -86,7 +86,7 @@ Public Attributes</h2></td></tr>
<tr class="memdesc:ad8006fb803185c0a699d30f3e9a865ae"><td class="mdescLeft">&#160;</td><td class="mdescRight">Minimum number of blocks to be always allocated in this pool, even if they stay empty. <a href="#ad8006fb803185c0a699d30f3e9a865ae">More...</a><br /></td></tr>
<tr class="separator:ad8006fb803185c0a699d30f3e9a865ae"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae41142f2834fcdc82baa4883c187b75c"><td class="memItemLeft" align="right" valign="top">size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_pool_create_info.html#ae41142f2834fcdc82baa4883c187b75c">maxBlockCount</a></td></tr>
<tr class="memdesc:ae41142f2834fcdc82baa4883c187b75c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Maximum number of blocks that can be allocated in this pool. <a href="#ae41142f2834fcdc82baa4883c187b75c">More...</a><br /></td></tr>
<tr class="memdesc:ae41142f2834fcdc82baa4883c187b75c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Maximum number of blocks that can be allocated in this pool. Optional. <a href="#ae41142f2834fcdc82baa4883c187b75c">More...</a><br /></td></tr>
<tr class="separator:ae41142f2834fcdc82baa4883c187b75c"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9437e43ffbb644dbbf7fc4e50cfad6aa"><td class="memItemLeft" align="right" valign="top">uint32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="struct_vma_pool_create_info.html#a9437e43ffbb644dbbf7fc4e50cfad6aa">frameInUseCount</a></td></tr>
<tr class="memdesc:a9437e43ffbb644dbbf7fc4e50cfad6aa"><td class="mdescLeft">&#160;</td><td class="mdescRight">Maximum number of additional frames that are in use at the same time as current frame. <a href="#a9437e43ffbb644dbbf7fc4e50cfad6aa">More...</a><br /></td></tr>
@ -141,7 +141,7 @@ Public Attributes</h2></td></tr>
</div><div class="memdoc">
<p>Maximum number of additional frames that are in use at the same time as current frame. </p>
<p>This value is used only when you make allocations with <code>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</code> flag. Such allocation cannot become lost if allocation.lastUseFrameIndex &gt;= allocator.currentFrameIndex - frameInUseCount.</p>
<p>This value is used only when you make allocations with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> flag. Such allocation cannot become lost if allocation.lastUseFrameIndex &gt;= allocator.currentFrameIndex - frameInUseCount.</p>
<p>For example, if you double-buffer your command buffers, so resources used for rendering in previous frame may still be in use by the GPU at the moment you allocate resources needed for the current frame, set this value to 1.</p>
<p>If you want to allow any allocations other than used in the current frame to become lost, set this value to 0. </p>
@ -159,7 +159,7 @@ Public Attributes</h2></td></tr>
</table>
</div><div class="memdoc">
<p>Maximum number of blocks that can be allocated in this pool. </p>
<p>Maximum number of blocks that can be allocated in this pool. Optional. </p>
<p>Optional. Set to 0 to use <code>SIZE_MAX</code>, which means no limit.</p>
<p>Set to same value as minBlockCount to have fixed amount of memory allocated throuout whole lifetime of this pool. </p>

View File

@ -67,9 +67,9 @@ $(function() {
</div><!--header-->
<div class="contents">
<div class="textblock"><ul>
<li>The library has no global state, so separate <code>VmaAllocator</code> objects can be used independently.</li>
<li>The library has no global state, so separate <code>VmaAllocator</code> objects can be used independently. There should be no need to create multiple such objects though - one per <code>VkDevice</code> is enough.</li>
<li>By default, all calls to functions that take <code>VmaAllocator</code> as first parameter are safe to call from multiple threads simultaneously because they are synchronized internally when needed.</li>
<li>When the allocator is created with <code>VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT</code> flag, calls to functions that take such <code>VmaAllocator</code> object must be synchronized externally.</li>
<li>When the allocator is created with <a class="el" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7ca4816ddaed324ba110172ca608a20f29d" title="Allocator and all objects created from it will not be synchronized internally, so you must guarantee ...">VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT</a> flag, calls to functions that take such <code>VmaAllocator</code> object must be synchronized externally.</li>
<li>Access to a <code>VmaAllocation</code> object must be externally synchronized. For example, you must not call <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> and <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a> from different threads at the same time if you pass the same <code>VmaAllocation</code> object to these functions. </li>
</ul>
</div></div><!-- contents -->

View File

@ -499,7 +499,7 @@ Functions</h2></td></tr>
<p>Set of callbacks that the library will call for <code>vkAllocateMemory</code> and <code>vkFreeMemory</code>. </p>
<p>Provided for informative purpose, e.g. to gather statistics about number of allocations or total amount of memory allocated in Vulkan.</p>
<p>Used in <a class="el" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e" title="Informative callbacks for vkAllocateMemory, vkFreeMemory. ">VmaAllocatorCreateInfo::pDeviceMemoryCallbacks</a>. </p>
<p>Used in <a class="el" href="struct_vma_allocator_create_info.html#af1380969b5e1ea4c3184a877892d260e" title="Informative callbacks for vkAllocateMemory, vkFreeMemory. Optional. ">VmaAllocatorCreateInfo::pDeviceMemoryCallbacks</a>. </p>
</div>
</div>
@ -650,23 +650,23 @@ Functions</h2></td></tr>
</td></tr>
<tr><td class="fieldname"><a id="ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff"></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_DEDICATED_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 <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f" title="Set this flag if the allocation should have its own memory block. ">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> and <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a89759603401014eb325eb22a3839f2ff" title="Set this flag to only try to allocate from existing VkDeviceMemory blocks and never create new such b...">VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT</a> 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="ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f"></a>VMA_ALLOCATION_CREATE_MAPPED_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>
<p>Pointer to mapped memory will be returned through <a class="el" href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2" title="Pointer to the beginning of this allocation as mapped data. ">VmaAllocationInfo::pMappedData</a>.</p>
<p>Is it valid to use this flag for allocation made from memory type that is not <code>HOST_VISIBLE</code>. This flag is then ignored and memory is not mapped. This is useful if you need an allocation that is efficient to use on GPU (<code>DEVICE_LOCAL</code>) and still want to map it directly if possible on platforms that support it (e.g. Intel GPU).</p>
<p>You should not use this flag together with <code>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</code>. </p>
<p>You should not use this flag together with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a>. </p>
</td></tr>
<tr><td class="fieldname"><a id="ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2"></a>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT&#160;</td><td class="fielddoc"><p>Allocation created with this flag can become lost as a result of another allocation with <code>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</code> flag, so you must check it before use.</p>
<tr><td class="fieldname"><a id="ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2"></a>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT&#160;</td><td class="fielddoc"><p>Allocation created with this flag can become lost as a result of another allocation with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a> flag, so you must check it before use.</p>
<p>To check if allocation is not lost, call <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> and check if <a class="el" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67" title="Handle to Vulkan memory object. ">VmaAllocationInfo::deviceMemory</a> is not <code>VK_NULL_HANDLE</code>.</p>
<p>For details about supporting lost allocations, see Lost Allocations chapter of User Guide on Main Page.</p>
<p>You should not use this flag together with <code>VMA_ALLOCATION_CREATE_MAPPED_BIT</code>. </p>
<p>You should not use this flag together with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a>. </p>
</td></tr>
<tr><td class="fieldname"><a id="ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e"></a>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT&#160;</td><td class="fielddoc"><p>While creating allocation using this flag, other allocations that were created with flag <code>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</code> can become lost.</p>
<tr><td class="fieldname"><a id="ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e"></a>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT&#160;</td><td class="fielddoc"><p>While creating allocation using this flag, other allocations that were created with flag <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> can become lost.</p>
<p>For details about supporting lost allocations, see Lost Allocations chapter of User Guide on Main Page. </p>
</td></tr>
<tr><td class="fieldname"><a id="ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520"></a>VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT&#160;</td><td class="fielddoc"><p>Set this flag to treat <a class="el" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19" title="Custom general-purpose pointer that will be stored in VmaAllocation, can be read as VmaAllocationInfo...">VmaAllocationCreateInfo::pUserData</a> as pointer to a null-terminated string. Instead of copying pointer value, a local copy of the string is made and stored in allocation's pUserData. The string is automatically freed together with the allocation. It is also used in <a class="el" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0" title="Builds and returns statistics as string in JSON format. ">vmaBuildStatsString()</a>. </p>
<tr><td class="fieldname"><a id="ad9889c10c798b040d59c92f257cae597aa6f24f821cd6a7c5e4a443f7bf59c520"></a>VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT&#160;</td><td class="fielddoc"><p>Set this flag to treat <a class="el" href="struct_vma_allocation_create_info.html#a8259e85c272683434f4abb4ddddffe19" title="Custom general-purpose pointer that will be stored in VmaAllocation, can be read as VmaAllocationInfo...">VmaAllocationCreateInfo::pUserData</a> as pointer to a null-terminated string. Instead of copying pointer value, a local copy of the string is made and stored in allocation's <code>pUserData</code>. The string is automatically freed together with the allocation. It is also used in <a class="el" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0" title="Builds and returns statistics as string in JSON format. ">vmaBuildStatsString()</a>. </p>
</td></tr>
<tr><td class="fieldname"><a id="ad9889c10c798b040d59c92f257cae597ae5633ec569f4899cf8f29e7385b2f882"></a>VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM&#160;</td><td class="fielddoc"></td></tr>
</table>
@ -691,7 +691,7 @@ Functions</h2></td></tr>
<p>Using this flag may increase performance because internal mutexes are not used. </p>
</td></tr>
<tr><td class="fieldname"><a id="a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878"></a>VMA_ALLOCATOR_CREATE_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>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 <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f" title="Set this flag if the allocation should have its own memory block. ">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> 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>
@ -727,7 +727,7 @@ Functions</h2></td></tr>
<li>Resources written and read by device, e.g. images used as attachments.</li>
<li>Resources transferred from host once (immutable) or infrequently and read by device multiple times, e.g. textures to be sampled, vertex buffers, uniform (constant) buffers, and majority of other types of resources used by device.</li>
</ul>
<p>Allocation may still end up in <code>HOST_VISIBLE</code> memory on some implementations. In such case, you are free to map it. You can use <code>VMA_ALLOCATION_CREATE_MAPPED_BIT</code> with this usage type. </p>
<p>Allocation may still end up in <code>HOST_VISIBLE</code> memory on some implementations. In such case, you are free to map it. You can use <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> with this usage type. </p>
</td></tr>
<tr><td class="fieldname"><a id="aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5"></a>VMA_MEMORY_USAGE_CPU_ONLY&#160;</td><td class="fielddoc"><p>Memory will be mappable on host. It usually means CPU (system) memory. Resources created in this pool may still be accessible to the device, but access to them can be slower. Guarantees to be <code>HOST_VISIBLE</code> and <code>HOST_COHERENT</code>. CPU read may be uncached. It is roughly equivalent of <code>D3D12_HEAP_TYPE_UPLOAD</code>.</p>
<p>Usage: Staging copy of resources used as transfer source. </p>
@ -1298,8 +1298,8 @@ 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_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_MAPPED_BIT</code> flag can be compacted. If not persistently mapped, memory will be mapped temporarily inside this function if needed.</li>
<li>You may pass allocations made with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f" title="Set this flag if the allocation should have its own memory block. ">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> but it makes no sense - they will never be moved.</li>
<li>Both allocations made with or without <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> flag can be compacted. If not persistently mapped, memory will be mapped temporarily inside this function if needed.</li>
<li>You must not pass same <code>VmaAllocation</code> object multiple times in pAllocations array.</li>
</ul>
<p>The function also frees empty <code>VkDeviceMemory</code> blocks.</p>
@ -1900,9 +1900,9 @@ Functions</h2></td></tr>
<p>Mapping is internally reference-counted and synchronized, so despite raw Vulkan function <code>vkMapMemory()</code> cannot be used to map same block of <code>VkDeviceMemory</code> multiple times simultaneously, it is safe to call this function on allocations assigned to the same memory block. Actual Vulkan memory will be mapped on first mapping and unmapped on last unmapping.</p>
<p>If the function succeeded, you must call <a class="el" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45" title="Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). ">vmaUnmapMemory()</a> to unmap the allocation when mapping is no longer needed or before freeing the allocation, at the latest.</p>
<p>It also safe to call this function multiple times on the same allocation. You must call <a class="el" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45" title="Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). ">vmaUnmapMemory()</a> same number of times as you called <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a>.</p>
<p>It is also safe to call this function on allocation created with <code>VMA_ALLOCATION_CREATE_MAPPED_BIT</code> flag. Its memory stays mapped all the time. You must still call <a class="el" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45" title="Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). ">vmaUnmapMemory()</a> same number of times as you called <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a>. You must not call <a class="el" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45" title="Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). ">vmaUnmapMemory()</a> additional time to free the "0-th" mapping made automatically due to <code>VMA_ALLOCATION_CREATE_MAPPED_BIT</code> flag.</p>
<p>It is also safe to call this function on allocation created with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> flag. Its memory stays mapped all the time. You must still call <a class="el" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45" title="Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). ">vmaUnmapMemory()</a> same number of times as you called <a class="el" href="vk__mem__alloc_8h.html#ad5bd1243512d099706de88168992f069" title="Maps memory represented by given allocation and returns pointer to it. ">vmaMapMemory()</a>. You must not call <a class="el" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45" title="Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). ">vmaUnmapMemory()</a> additional time to free the "0-th" mapping made automatically due to <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a11da372cc3a82931c5e5d6146cd9dd1f" title="Set this flag to use a memory that will be persistently mapped and retrieve pointer to it...">VMA_ALLOCATION_CREATE_MAPPED_BIT</a> flag.</p>
<p>This function fails when used on allocation made in memory type that is not <code>HOST_VISIBLE</code>.</p>
<p>This function always fails when called for allocation that was created with <code>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</code> flag. Such allocations cannot be mapped. </p>
<p>This function always fails when called for allocation that was created with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> flag. Such allocations cannot be mapped. </p>
</div>
</div>
@ -1939,8 +1939,8 @@ Functions</h2></td></tr>
</div><div class="memdoc">
<p>Sets pUserData in given allocation to new value. </p>
<p>If the allocation was created with VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT, pUserData must be either null, or pointer to a null-terminated string. The function makes local copy of the string and sets it as allocation's pUserData. String passed as pUserData doesn't need to be valid for whole lifetime of the allocation - you can free it after this call. String previously pointed by allocation's pUserData is freed from memory.</p>
<p>If the flag was not used, the value of pointer pUserData is just copied to allocation's pUserData. It is opaque, so you can use it however you want - e.g. as a pointer, ordinal number or some handle to you own data. </p>
<p>If the allocation was created with VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT, pUserData must be either null, or pointer to a null-terminated string. The function makes local copy of the string and sets it as allocation's <code>pUserData</code>. String passed as pUserData doesn't need to be valid for whole lifetime of the allocation - you can free it after this call. String previously pointed by allocation's pUserData is freed from memory.</p>
<p>If the flag was not used, the value of pointer <code>pUserData</code> is just copied to allocation's <code>pUserData</code>. It is opaque, so you can use it however you want - e.g. as a pointer, ordinal number or some handle to you own data. </p>
</div>
</div>
@ -1971,7 +1971,7 @@ Functions</h2></td></tr>
</div><div class="memdoc">
<p>Sets index of the current frame. </p>
<p>This function must be used if you make allocations with <code>VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</code> and <code>VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</code> flags to inform the allocator when a new frame begins. Allocations queried using <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> cannot become lost in the current frame. </p>
<p>This function must be used if you make allocations with <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a5f436af6c8fe8540573a6d22627a6fd2">VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT</a> and <a class="el" href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597a68686d0ce9beb0d4d1b9f2b8b1389a7e">VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT</a> flags to inform the allocator when a new frame begins. Allocations queried using <a class="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation. ">vmaGetAllocationInfo()</a> cannot become lost in the current frame. </p>
</div>
</div>

File diff suppressed because one or more lines are too long

View File

@ -74,7 +74,7 @@ $(function() {
<li>VK_KHR_dedicated_allocation</li>
</ul>
<p>If you enabled these extensions:</p>
<p>2 . Use <code>VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</code> flag when creating your <code>VmaAllocator</code> to inform the library that you enabled required extensions and you want the library to use them.</p>
<p>2 . Use <a class="el" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878" title="Enables usage of VK_KHR_dedicated_allocation extension. ">VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</a> flag when creating your <code>VmaAllocator</code> to inform the library that you enabled required extensions and you want the library to use them.</p>
<div class="fragment"><div class="line">allocatorInfo.<a class="code" href="struct_vma_allocator_create_info.html#a392ea2ecbaff93f91a7c49f735ad4346">flags</a> |= <a class="code" href="vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7cace7da7cc6e71a625dfa763c55a597878">VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT</a>;</div><div class="line"></div><div class="line"><a class="code" href="vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb">vmaCreateAllocator</a>(&amp;allocatorInfo, &amp;allocator);</div></div><!-- fragment --><p>That's all. The extension will be automatically used whenever you create a buffer using <a class="el" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer()</a> or image using <a class="el" href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73" title="Function similar to vmaCreateBuffer(). ">vmaCreateImage()</a>.</p>
<p>When using the extension together with Vulkan Validation Layer, you will receive warnings like this: </p><pre class="fragment">vkBindBufferMemory(): Binding memory to buffer 0x33 but vkGetBufferMemoryRequirements() has not been called on that buffer.
</pre><p>It is OK, you should just ignore it. It happens because you use function <code>vkGetBufferMemoryRequirements2KHR()</code> instead of standard <code>vkGetBufferMemoryRequirements()</code>, while the validation layer seems to be unaware of it.</p>

View File

@ -208,7 +208,7 @@ If you inspected memory types available on the physical device and you have
a preference for memory types that you want to use, you can fill member
VmaAllocationCreateInfo::memoryTypeBits. It is a bit mask, where each bit set
means that a memory type with that index is allowed to be used for the
allocation. Special value 0, just like UINT32_MAX, means there are no
allocation. Special value 0, just like `UINT32_MAX`, means there are no
restrictions to memory type index.
Please note that this member is NOT just a memory type index.
@ -285,7 +285,7 @@ vmaUnmapMemory(allocator, constantBufferAllocation);
Kepping your memory persistently mapped is generally OK in Vulkan.
You don't need to unmap it before using its data on the GPU.
The library provides a special feature designed for that:
Allocations made with `VMA_ALLOCATION_CREATE_MAPPED_BIT` flag set in
Allocations made with #VMA_ALLOCATION_CREATE_MAPPED_BIT flag set in
VmaAllocationCreateInfo::flags stay mapped all the time,
so you can just access CPU pointer to it any time
without a need to call any "map" or "unmap" function.
@ -314,7 +314,7 @@ There are some exceptions though, when you should consider mapping memory only f
- When operating system is Windows 7 or 8.x (Windows 10 is not affected because it uses WDDM2),
device is discrete AMD GPU,
and memory type is the special 256 MiB pool of `DEVICE_LOCAL + HOST_VISIBLE` memory
(selected when you use `VMA_MEMORY_USAGE_CPU_TO_GPU`),
(selected when you use #VMA_MEMORY_USAGE_CPU_TO_GPU),
then whenever a memory block allocated from this memory type stays mapped
for the time of any call to `vkQueueSubmit()` or `vkQueuePresentKHR()`, this
block is migrated by WDDM to system RAM, which degrades performance. It doesn't
@ -347,7 +347,7 @@ if((memFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)
}
\endcode
Please note that memory allocated with `VMA_MEMORY_USAGE_CPU_ONLY` is guaranteed to be host coherent.
Please note that memory allocated with #VMA_MEMORY_USAGE_CPU_ONLY is guaranteed to be host coherent.
Also, Windows drivers from all 3 PC GPU vendors (AMD, Intel, NVIDIA)
currently provide `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT` flag on all memory types that are
@ -365,8 +365,8 @@ instead of launching a transfer operation.
In order to do that: inspect `allocInfo.memoryType`, call vmaGetMemoryTypeProperties(),
and look for `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` flag in properties of that memory type.
You can even use `VMA_ALLOCATION_CREATE_MAPPED_BIT` flag while creating allocations
that are not necessarily `HOST_VISIBLE` (e.g. using `VMA_MEMORY_USAGE_GPU_ONLY`).
You can even use #VMA_ALLOCATION_CREATE_MAPPED_BIT flag while creating allocations
that are not necessarily `HOST_VISIBLE` (e.g. using #VMA_MEMORY_USAGE_GPU_ONLY).
If the allocation ends up in memory type that is `HOST_VISIBLE`, it will be persistently mapped and you can use it directly.
If not, the flag is just ignored.
Example:
@ -394,7 +394,7 @@ if(allocInfo.pUserData != nullptr)
else
{
// Allocation ended up in non-mappable memory.
// You need to create CPU-side copy in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer.
// You need to create CPU-side buffer in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer.
}
\endcode
@ -521,7 +521,7 @@ for the new ones, effectively using VRAM (or a cartain memory pool) as a form of
cache. Vulkan Memory Allocator can help you with that by supporting a concept of
"lost allocations".
To create an allocation that can become lost, include `VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT`
To create an allocation that can become lost, include #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT
flag in VmaAllocationCreateInfo::flags. Before using a buffer or image bound to
such allocation in every new frame, you need to query it if it's not lost. To
check it: call vmaGetAllocationInfo() and see if VmaAllocationInfo::deviceMemory
@ -530,16 +530,16 @@ buffer/image bound to it. You mustn't forget to destroy this allocation and this
buffer/image.
To create an allocation that can make some other allocations lost to make room
for it, use `VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT` flag. You will
usually use both flags `VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT` and
`VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT` at the same time.
for it, use #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flag. You will
usually use both flags #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT and
#VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT at the same time.
Warning! Current implementation uses quite naive, brute force algorithm,
which can make allocation calls that use `VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT`
which can make allocation calls that use #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT
flag quite slow. A new, more optimal algorithm and data structure to speed this
up is planned for the future.
<b>When interleaving creation of new allocations with usage of existing ones,
<b>Q: When interleaving creation of new allocations with usage of existing ones,
how do you make sure that an allocation won't become lost while it's used in the
current frame?</b>
@ -549,7 +549,7 @@ atomically marks it as used in the current frame, which makes it impossible to
become lost in that frame. It uses lockless algorithm, so it works fast and
doesn't involve locking any internal mutex.
<b>What if my allocation may still be in use by the GPU when it's rendering a
<b>Q: What if my allocation may still be in use by the GPU when it's rendering a
previous frame while I already submit new frame on the CPU?</b>
You can make sure that allocations "touched" by vmaGetAllocationInfo() will not
@ -557,7 +557,7 @@ become lost for a number of additional frames back from the current one by
specifying this number as VmaAllocatorCreateInfo::frameInUseCount (for default
memory pool) and VmaPoolCreateInfo::frameInUseCount (for custom pool).
<b>How do you inform the library when new frame starts?</b>
<b>Q: How do you inform the library when new frame starts?</b>
You need to call function vmaSetCurrentFrameIndex().
@ -615,11 +615,11 @@ The library uses following algorithm for allocation, in order:
-# Try to find free range of memory in existing blocks.
-# If failed, try to create a new block of `VkDeviceMemory`, with preferred block size.
-# If failed, try to create such block with size/2 and size/4.
-# If failed and `VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT` flag was
-# If failed and #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flag was
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_DEDICATED_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`.
@ -667,7 +667,7 @@ vmaBuildStatsString(), in hexadecimal form.
There is alternative mode available where `pUserData` pointer is used to point to
a null-terminated string, giving a name to the allocation. To use this mode,
set `VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT` flag in VmaAllocationCreateInfo::flags.
set #VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT flag in VmaAllocationCreateInfo::flags.
Then `pUserData` passed as VmaAllocationCreateInfo::pUserData or argument to
vmaSetAllocationUserData() must be either null or pointer to a null-terminated string.
The library creates internal copy of the string, so the pointer you pass doesn't need
@ -764,7 +764,7 @@ If yes, enable them (fill `VkDeviceCreateInfo::ppEnabledExtensionNames`).
If you enabled these extensions:
2 . Use `VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT` flag when creating
2 . Use #VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT flag when creating
your `VmaAllocator` to inform the library that you enabled required extensions
and you want the library to use them.
@ -798,10 +798,11 @@ To learn more about this extension, see:
- The library has no global state, so separate `VmaAllocator` objects can be used
independently.
There should be no need to create multiple such objects though - one per `VkDevice` is enough.
- By default, all calls to functions that take `VmaAllocator` as first parameter
are safe to call from multiple threads simultaneously because they are
synchronized internally when needed.
- When the allocator is created with `VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT`
- When the allocator is created with #VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT
flag, calls to functions that take such `VmaAllocator` object must be
synchronized externally.
- Access to a `VmaAllocation` object must be externally synchronized. For example,
@ -865,7 +866,7 @@ typedef enum VmaAllocatorCreateFlagBits {
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
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.
@ -922,13 +923,13 @@ typedef struct VmaAllocatorCreateInfo
/// Vulkan device.
/** It must be valid throughout whole lifetime of created allocator. */
VkDevice device;
/// Preferred size of a single `VkDeviceMemory` block to be allocated from large heaps > 1 GiB.
/// Preferred size of a single `VkDeviceMemory` block to be allocated from large heaps > 1 GiB. Optional.
/** Set to 0 to use default, which is currently 256 MiB. */
VkDeviceSize preferredLargeHeapBlockSize;
/// Custom CPU memory allocation callbacks.
/// Custom CPU memory allocation callbacks. Optional.
/** Optional, can be null. When specified, will also be used for all CPU-side memory allocations. */
const VkAllocationCallbacks* pAllocationCallbacks;
/// Informative callbacks for vkAllocateMemory, vkFreeMemory.
/// Informative callbacks for `vkAllocateMemory`, `vkFreeMemory`. Optional.
/** Optional, can be null. */
const VmaDeviceMemoryCallbacks* pDeviceMemoryCallbacks;
/** \brief Maximum number of additional frames that are in use at the same time as current frame.
@ -945,7 +946,7 @@ 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.
/** \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
@ -1022,8 +1023,8 @@ void vmaGetMemoryTypeProperties(
/** \brief Sets index of the current frame.
This function must be used if you make allocations with
`VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT` and
`VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT` flags to inform the allocator
#VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT and
#VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flags to inform the allocator
when a new frame begins. Allocations queried using vmaGetAllocationInfo() cannot
become lost in the current frame.
*/
@ -1102,7 +1103,7 @@ typedef enum VmaMemoryUsage
Allocation may still end up in `HOST_VISIBLE` memory on some implementations.
In such case, you are free to map it.
You can use `VMA_ALLOCATION_CREATE_MAPPED_BIT` with this usage type.
You can use #VMA_ALLOCATION_CREATE_MAPPED_BIT with this usage type.
*/
VMA_MEMORY_USAGE_GPU_ONLY = 1,
/** Memory will be mappable on host.
@ -1154,8 +1155,8 @@ typedef enum VmaAllocationCreateFlagBits {
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_DEDICATED_MEMORY_BIT` and
`VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT` at the same time. It makes no sense.
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. */
VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT = 0x00000002,
@ -1169,11 +1170,11 @@ typedef enum VmaAllocationCreateFlagBits {
(`DEVICE_LOCAL`) and still want to map it directly if possible on platforms that
support it (e.g. Intel GPU).
You should not use this flag together with `VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT`.
You should not use this flag together with #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT.
*/
VMA_ALLOCATION_CREATE_MAPPED_BIT = 0x00000004,
/** Allocation created with this flag can become lost as a result of another
allocation with `VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT` flag, so you
allocation with #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flag, so you
must check it before use.
To check if allocation is not lost, call vmaGetAllocationInfo() and check if
@ -1182,11 +1183,11 @@ typedef enum VmaAllocationCreateFlagBits {
For details about supporting lost allocations, see Lost Allocations
chapter of User Guide on Main Page.
You should not use this flag together with `VMA_ALLOCATION_CREATE_MAPPED_BIT`.
You should not use this flag together with #VMA_ALLOCATION_CREATE_MAPPED_BIT.
*/
VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT = 0x00000008,
/** While creating allocation using this flag, other allocations that were
created with flag `VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT` can become lost.
created with flag #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT can become lost.
For details about supporting lost allocations, see Lost Allocations
chapter of User Guide on Main Page.
@ -1194,7 +1195,7 @@ typedef enum VmaAllocationCreateFlagBits {
VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT = 0x00000010,
/** Set this flag to treat VmaAllocationCreateInfo::pUserData as pointer to a
null-terminated string. Instead of copying pointer value, a local copy of the
string is made and stored in allocation's pUserData. The string is automatically
string is made and stored in allocation's `pUserData`. The string is automatically
freed together with the allocation. It is also used in vmaBuildStatsString().
*/
VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT = 0x00000020,
@ -1209,7 +1210,7 @@ typedef struct VmaAllocationCreateInfo
VmaAllocationCreateFlags flags;
/** \brief Intended usage of memory.
You can leave `VMA_MEMORY_USAGE_UNKNOWN` if you specify memory requirements in other way. \n
You can leave #VMA_MEMORY_USAGE_UNKNOWN if you specify memory requirements in other way. \n
If `pool` is not null, this member is ignored.
*/
VmaMemoryUsage usage;
@ -1239,7 +1240,7 @@ typedef struct VmaAllocationCreateInfo
VmaPool pool;
/** \brief Custom general-purpose pointer that will be stored in VmaAllocation, can be read as VmaAllocationInfo::pUserData and changed using vmaSetAllocationUserData().
If `VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT` is used, it must be either
If #VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT is used, it must be either
null or pointer to a null-terminated string. The string will be then copied to
internal buffer, so it doesn't need to be valid after allocation call.
*/
@ -1348,7 +1349,7 @@ typedef struct VmaPoolCreateInfo {
Set to 0 to have no preallocated blocks and let the pool be completely empty.
*/
size_t minBlockCount;
/** \brief Maximum number of blocks that can be allocated in this pool.
/** \brief Maximum number of blocks that can be allocated in this pool. Optional.
Optional. Set to 0 to use `SIZE_MAX`, which means no limit.
@ -1359,7 +1360,7 @@ typedef struct VmaPoolCreateInfo {
/** \brief Maximum number of additional frames that are in use at the same time as current frame.
This value is used only when you make allocations with
`VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT` flag. Such allocation cannot become
#VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag. Such allocation cannot become
lost if allocation.lastUseFrameIndex >= allocator.currentFrameIndex - frameInUseCount.
For example, if you double-buffer your command buffers, so resources used for
@ -1467,7 +1468,7 @@ typedef struct VmaAllocationInfo {
/** \brief Pointer to the beginning of this allocation as mapped data.
If the allocation hasn't been mapped using vmaMapMemory() and hasn't been
created with `VMA_ALLOCATION_CREATE_MAPPED_BIT` flag, this value null.
created with #VMA_ALLOCATION_CREATE_MAPPED_BIT flag, this value null.
It can change after call to vmaMapMemory(), vmaUnmapMemory().
It can also change after call to vmaDefragment() if this allocation is passed to the function.
@ -1542,13 +1543,13 @@ VkBool32 vmaTouchAllocation(
If the allocation was created with VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT,
pUserData must be either null, or pointer to a null-terminated string. The function
makes local copy of the string and sets it as allocation's pUserData. String
makes local copy of the string and sets it as allocation's `pUserData`. String
passed as pUserData doesn't need to be valid for whole lifetime of the allocation -
you can free it after this call. String previously pointed by allocation's
pUserData is freed from memory.
If the flag was not used, the value of pointer pUserData is just copied to
allocation's pUserData. It is opaque, so you can use it however you want - e.g.
If the flag was not used, the value of pointer `pUserData` is just copied to
allocation's `pUserData`. It is opaque, so you can use it however you want - e.g.
as a pointer, ordinal number or some handle to you own data.
*/
void vmaSetAllocationUserData(
@ -1592,16 +1593,16 @@ It also safe to call this function multiple times on the same allocation. You
must call vmaUnmapMemory() same number of times as you called vmaMapMemory().
It is also safe to call this function on allocation created with
`VMA_ALLOCATION_CREATE_MAPPED_BIT` flag. Its memory stays mapped all the time.
#VMA_ALLOCATION_CREATE_MAPPED_BIT flag. Its memory stays mapped all the time.
You must still call vmaUnmapMemory() same number of times as you called
vmaMapMemory(). You must not call vmaUnmapMemory() additional time to free the
"0-th" mapping made automatically due to `VMA_ALLOCATION_CREATE_MAPPED_BIT` flag.
"0-th" mapping made automatically due to #VMA_ALLOCATION_CREATE_MAPPED_BIT flag.
This function fails when used on allocation made in memory type that is not
`HOST_VISIBLE`.
This function always fails when called for allocation that was created with
`VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT` flag. Such allocations cannot be
#VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag. Such allocations cannot be
mapped.
*/
VkResult vmaMapMemory(
@ -1660,9 +1661,9 @@ 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_DEDICATED_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_MAPPED_BIT`
- Both allocations made with or without #VMA_ALLOCATION_CREATE_MAPPED_BIT
flag can be compacted. If not persistently mapped, memory will be mapped
temporarily inside this function if needed.
- You must not pass same `VmaAllocation` object multiple times in pAllocations array.