You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<li>It temporarily maps entire memory blocks when necessary.</li>
90
90
<li>It moves data using <code>memmove()</code> function.</li>
91
91
</ul>
92
-
<divclass="fragment"><divclass="line"><spanclass="comment">// Given following variables already initialized:</span></div><divclass="line">VkDevice device;</div><divclass="line"><aclass="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator;</div><divclass="line">std::vector<VkBuffer> buffers;</div><divclass="line">std::vector<VmaAllocation> allocations;</div><divclass="line"></div><divclass="line"></div><divclass="line"><spanclass="keyword">const</span> uint32_t allocCount = (uint32_t)allocations.size();</div><divclass="line">std::vector<VkBool32> allocationsChanged(allocCount);</div><divclass="line"></div><divclass="line"><aclass="code" href="struct_vma_defragmentation_info2.html">VmaDefragmentationInfo2</a> defragInfo = {};</div><divclass="line">defragInfo.<aclass="code" href="struct_vma_defragmentation_info2.html#a3cf86ab32c1da779b4923d301a3056ba">allocationCount</a> = allocCount;</div><divclass="line">defragInfo.<aclass="code" href="struct_vma_defragmentation_info2.html#a8943f8d65969ce8e2189a1cdf3205e96">pAllocations</a> = allocations.data();</div><divclass="line">defragInfo.<aclass="code" href="struct_vma_defragmentation_info2.html#a76d51a644dc7f5405d0cdd0025ecd0cc">pAllocationsChanged</a> = allocationsChanged.data();</div><divclass="line">defragInfo.<aclass="code" href="struct_vma_defragmentation_info2.html#af78e1ea40c22d85137b65f6b384a4d0a">maxCpuBytesToMove</a> = VK_WHOLE_SIZE; <spanclass="comment">// No limit.</span></div><divclass="line">defragInfo.<aclass="code" href="struct_vma_defragmentation_info2.html#a94c2c7223d52878445a8cccce396b671">maxCpuAllocationsToMove</a> = UINT32_MAX; <spanclass="comment">// No limit.</span></div><divclass="line"></div><divclass="line"><aclass="code" href="struct_vma_defragmentation_context.html">VmaDefragmentationContext</a> defragCtx;</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a36ba776fd7fd5cb1e9359fdc0d8e6e8a">vmaDefragmentationBegin</a>(allocator, &defragInfo, <spanclass="keyword">nullptr</span>, &defragCtx);</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a8774e20e91e245aae959ba63efa15dd2">vmaDefragmentationEnd</a>(allocator, defragCtx);</div><divclass="line"></div><divclass="line"><spanclass="keywordflow">for</span>(uint32_t i = 0; i < allocCount; ++i)</div><divclass="line">{</div><divclass="line"><spanclass="keywordflow">if</span>(allocationsChanged[i])</div><divclass="line"> {</div><divclass="line"><spanclass="comment">// Destroy buffer that is immutably bound to memory region which is no longer valid.</span></div><divclass="line"> vkDestroyBuffer(device, buffers[i], <spanclass="keyword">nullptr</span>);</div><divclass="line"></div><divclass="line"><spanclass="comment">// Create new buffer with same parameters.</span></div><divclass="line"> VkBufferCreateInfo bufferInfo = ...;</div><divclass="line"> vkCreateBuffer(device, &bufferInfo, <spanclass="keyword">nullptr</span>, &buffers[i]);</div><divclass="line"></div><divclass="line"><spanclass="comment">// You can make dummy call to vkGetBufferMemoryRequirements here to silence validation layer warning.</span></div><divclass="line"></div><divclass="line"><spanclass="comment">// Bind new buffer to new memory region. Data contained in it is already moved.</span></div><divclass="line"><aclass="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b">vmaGetAllocationInfo</a>(allocator, allocations[i], &allocInfo);</div><divclass="line"> vkBindBufferMemory(device, buffers[i], allocInfo.<aclass="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a>, allocInfo.<aclass="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a>);</div><divclass="line"> }</div><divclass="line">}</div></div><!-- fragment --><p>Filling <aclass="el" href="struct_vma_defragmentation_info2.html#a76d51a644dc7f5405d0cdd0025ecd0cc" title="Optional, output. Pointer to array that will be filled with information whether the allocation at cer...">VmaDefragmentationInfo2::pAllocationsChanged</a> is optional. This output array tells whether particular allocation in <aclass="el" href="struct_vma_defragmentation_info2.html#a8943f8d65969ce8e2189a1cdf3205e96" title="Pointer to array of allocations that can be defragmented. ">VmaDefragmentationInfo2::pAllocations</a> at the same index has been modified during defragmentation. You can pass null, but you then need to query every allocation passed to defragmentation for new parameters using <aclass="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation and atomically marks it as used in current fra...">vmaGetAllocationInfo()</a> if you might need to recreate and rebind a buffer or image associated with it.</p>
92
+
<divclass="fragment"><divclass="line"><spanclass="comment">// Given following variables already initialized:</span></div><divclass="line">VkDevice device;</div><divclass="line"><aclass="code" href="struct_vma_allocator.html">VmaAllocator</a> allocator;</div><divclass="line">std::vector<VkBuffer> buffers;</div><divclass="line">std::vector<VmaAllocation> allocations;</div><divclass="line"></div><divclass="line"></div><divclass="line"><spanclass="keyword">const</span> uint32_t allocCount = (uint32_t)allocations.size();</div><divclass="line">std::vector<VkBool32> allocationsChanged(allocCount);</div><divclass="line"></div><divclass="line"><aclass="code" href="struct_vma_defragmentation_info2.html">VmaDefragmentationInfo2</a> defragInfo = {};</div><divclass="line">defragInfo.<aclass="code" href="struct_vma_defragmentation_info2.html#a3cf86ab32c1da779b4923d301a3056ba">allocationCount</a> = allocCount;</div><divclass="line">defragInfo.<aclass="code" href="struct_vma_defragmentation_info2.html#a8943f8d65969ce8e2189a1cdf3205e96">pAllocations</a> = allocations.data();</div><divclass="line">defragInfo.<aclass="code" href="struct_vma_defragmentation_info2.html#a76d51a644dc7f5405d0cdd0025ecd0cc">pAllocationsChanged</a> = allocationsChanged.data();</div><divclass="line">defragInfo.<aclass="code" href="struct_vma_defragmentation_info2.html#af78e1ea40c22d85137b65f6b384a4d0a">maxCpuBytesToMove</a> = VK_WHOLE_SIZE; <spanclass="comment">// No limit.</span></div><divclass="line">defragInfo.<aclass="code" href="struct_vma_defragmentation_info2.html#a94c2c7223d52878445a8cccce396b671">maxCpuAllocationsToMove</a> = UINT32_MAX; <spanclass="comment">// No limit.</span></div><divclass="line"></div><divclass="line"><aclass="code" href="struct_vma_defragmentation_context.html">VmaDefragmentationContext</a> defragCtx;</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a36ba776fd7fd5cb1e9359fdc0d8e6e8a">vmaDefragmentationBegin</a>(allocator, &defragInfo, <spanclass="keyword">nullptr</span>, &defragCtx);</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a8774e20e91e245aae959ba63efa15dd2">vmaDefragmentationEnd</a>(allocator, defragCtx);</div><divclass="line"></div><divclass="line"><spanclass="keywordflow">for</span>(uint32_t i = 0; i < allocCount; ++i)</div><divclass="line">{</div><divclass="line"><spanclass="keywordflow">if</span>(allocationsChanged[i])</div><divclass="line"> {</div><divclass="line"><spanclass="comment">// Destroy buffer that is immutably bound to memory region which is no longer valid.</span></div><divclass="line"> vkDestroyBuffer(device, buffers[i], <spanclass="keyword">nullptr</span>);</div><divclass="line"></div><divclass="line"><spanclass="comment">// Create new buffer with same parameters.</span></div><divclass="line"> VkBufferCreateInfo bufferInfo = ...;</div><divclass="line"> vkCreateBuffer(device, &bufferInfo, <spanclass="keyword">nullptr</span>, &buffers[i]);</div><divclass="line"></div><divclass="line"><spanclass="comment">// You can make dummy call to vkGetBufferMemoryRequirements here to silence validation layer warning.</span></div><divclass="line"></div><divclass="line"><spanclass="comment">// Bind new buffer to new memory region. Data contained in it is already moved.</span></div><divclass="line"><aclass="code" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><divclass="line"><aclass="code" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b">vmaGetAllocationInfo</a>(allocator, allocations[i], &allocInfo);</div><divclass="line"> vkBindBufferMemory(device, buffers[i], allocInfo.<aclass="code" href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a>, allocInfo.<aclass="code" href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a>);</div><divclass="line"> }</div><divclass="line">}</div></div><!-- fragment --><p>Setting <aclass="el" href="struct_vma_defragmentation_info2.html#a76d51a644dc7f5405d0cdd0025ecd0cc" title="Optional, output. Pointer to array that will be filled with information whether the allocation at cer...">VmaDefragmentationInfo2::pAllocationsChanged</a> is optional. This output array tells whether particular allocation in <aclass="el" href="struct_vma_defragmentation_info2.html#a8943f8d65969ce8e2189a1cdf3205e96" title="Pointer to array of allocations that can be defragmented. ">VmaDefragmentationInfo2::pAllocations</a> at the same index has been modified during defragmentation. You can pass null, but you then need to query every allocation passed to defragmentation for new parameters using <aclass="el" href="vk__mem__alloc_8h.html#a86dd08aba8633bfa4ad0df2e76481d8b" title="Returns current information about specified allocation and atomically marks it as used in current fra...">vmaGetAllocationInfo()</a> if you might need to recreate and rebind a buffer or image associated with it.</p>
93
93
<p>If you use <aclass="el" href="choosing_memory_type.html#choosing_memory_type_custom_memory_pools">Custom memory pools</a>, you can fill <aclass="el" href="struct_vma_defragmentation_info2.html#a7e70aa2a1081d849dcc7829b19d3ec9d" title="Numer of pools in pPools array. ">VmaDefragmentationInfo2::poolCount</a> and <aclass="el" href="struct_vma_defragmentation_info2.html#a0b3effd57f3fcdeb2ed62210b4ef20e1" title="Either null or pointer to array of pools to be defragmented. ">VmaDefragmentationInfo2::pPools</a> instead of <aclass="el" href="struct_vma_defragmentation_info2.html#a3cf86ab32c1da779b4923d301a3056ba" title="Number of allocations in pAllocations array. ">VmaDefragmentationInfo2::allocationCount</a> and <aclass="el" href="struct_vma_defragmentation_info2.html#a8943f8d65969ce8e2189a1cdf3205e96" title="Pointer to array of allocations that can be defragmented. ">VmaDefragmentationInfo2::pAllocations</a> to defragment all allocations in given pools. You cannot use <aclass="el" href="struct_vma_defragmentation_info2.html#a76d51a644dc7f5405d0cdd0025ecd0cc" title="Optional, output. Pointer to array that will be filled with information whether the allocation at cer...">VmaDefragmentationInfo2::pAllocationsChanged</a> in that case. You can also combine both methods.</p>
<p>If you want to implement your own, custom defragmentation algorithm, there is infrastructure prepared for that, but it is not exposed through the library API - you need to hack its source code. Here are steps needed to do this:</p>
113
113
<oltype="1">
114
-
<li>Main thing you need to do is to define your own class derived from base abstract class <code>VmaDefragmentationAlgorithm</code> and implement your version of its pure virtual method. See definition and comments of this class for details.</li>
114
+
<li>Main thing you need to do is to define your own class derived from base abstract class <code>VmaDefragmentationAlgorithm</code> and implement your version of its pure virtual methods. See definition and comments of this class for details.</li>
115
115
<li>Your code needs to interact with device memory block metadata. If you need more access to its data than it's provided by its public interface, declare your new class as a friend class e.g. in class <code>VmaBlockMetadata_Generic</code>.</li>
116
-
<li>If you want to create a flag that would enable your algorithm or pass some additional flags to configure it, define some enum with such flags and use them in <aclass="el" href="struct_vma_defragmentation_info2.html#a53e844ee5633e229cf6daf14b2d9fff9" title="Reserved for future use. Should be 0. ">VmaDefragmentationInfo2::flags</a>.</li>
116
+
<li>If you want to create a flag that would enable your algorithm or pass some additional flags to configure it, add them to <code>VmaDefragmentationFlagBits</code> and use them in <aclass="el" href="struct_vma_defragmentation_info2.html#a53e844ee5633e229cf6daf14b2d9fff9" title="Reserved for future use. Should be 0. ">VmaDefragmentationInfo2::flags</a>.</li>
117
117
<li>Modify function <code>VmaBlockVectorDefragmentationContext::Begin</code> to create object of your new class whenever needed. </li>
0 commit comments