mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
synced 2024-11-24 21:10:12 +00:00
Fixed threading bug with mapping vs binding. Added functions vmaBindBufferMemory, vmaBindImageMemory. Removed class VmaDeviceMemoryMapping. Minor fixes in documentation.
This commit is contained in:
parent
57fa5580c0
commit
ba335cf8c0
@ -70,7 +70,7 @@ $(function() {
|
||||
<ol type="1">
|
||||
<li>If you just want to find memory type index that meets your requirements, you can use function <a class="el" href="vk__mem__alloc_8h.html#aef15a94b58fbcb0fe706d5720e84a74a" title="Helps to find memoryTypeIndex, given memoryTypeBits and VmaAllocationCreateInfo. ">vmaFindMemoryTypeIndex()</a>.</li>
|
||||
<li>If you want to allocate a region of device memory without association with any specific image or buffer, you can use function <a class="el" href="vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8" title="General purpose memory allocation. ">vmaAllocateMemory()</a>. Usage of this function is not recommended and usually not needed.</li>
|
||||
<li>If you already have a buffer or an image created, you want to allocate memory for it and then you will bind it yourself, you can use function <a class="el" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>, <a class="el" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb" title="Function similar to vmaAllocateMemoryForBuffer(). ">vmaAllocateMemoryForImage()</a>.</li>
|
||||
<li>If you already have a buffer or an image created, you want to allocate memory for it and then you will bind it yourself, you can use function <a class="el" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>, <a class="el" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb" title="Function similar to vmaAllocateMemoryForBuffer(). ">vmaAllocateMemoryForImage()</a>. For binding you should use functions: <a class="el" href="vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470" title="Binds buffer to allocation. ">vmaBindBufferMemory()</a>, <a class="el" href="vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5" title="Binds image to allocation. ">vmaBindImageMemory()</a>.</li>
|
||||
<li>If you want to create a buffer or an image, allocate memory for it and bind them together, all in one call, you can use function <a class="el" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer()</a>, <a class="el" href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73" title="Function similar to vmaCreateBuffer(). ">vmaCreateImage()</a>. This is the recommended way to use this library.</li>
|
||||
</ol>
|
||||
<p>When using 3. or 4., the library internally queries Vulkan for memory types supported for that buffer or image (function <code>vkGetBufferMemoryRequirements()</code>) and uses only one of these types.</p>
|
||||
|
@ -158,6 +158,12 @@ $(function() {
|
||||
<li>VmaAllocatorCreateInfo
|
||||
: <a class="el" href="vk__mem__alloc_8h.html#ae0f6d1d733dded220d28134da46b4283">vk_mem_alloc.h</a>
|
||||
</li>
|
||||
<li>vmaBindBufferMemory()
|
||||
: <a class="el" href="vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470">vk_mem_alloc.h</a>
|
||||
</li>
|
||||
<li>vmaBindImageMemory()
|
||||
: <a class="el" href="vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5">vk_mem_alloc.h</a>
|
||||
</li>
|
||||
<li>vmaBuildStatsString()
|
||||
: <a class="el" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0">vk_mem_alloc.h</a>
|
||||
</li>
|
||||
|
@ -70,6 +70,12 @@ $(function() {
|
||||
<li>vmaAllocateMemoryForImage()
|
||||
: <a class="el" href="vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb">vk_mem_alloc.h</a>
|
||||
</li>
|
||||
<li>vmaBindBufferMemory()
|
||||
: <a class="el" href="vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470">vk_mem_alloc.h</a>
|
||||
</li>
|
||||
<li>vmaBindImageMemory()
|
||||
: <a class="el" href="vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5">vk_mem_alloc.h</a>
|
||||
</li>
|
||||
<li>vmaBuildStatsString()
|
||||
: <a class="el" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0">vk_mem_alloc.h</a>
|
||||
</li>
|
||||
|
@ -50,6 +50,8 @@ var searchData=
|
||||
['vmaallocatorcreateflagbits',['VmaAllocatorCreateFlagBits',['../vk__mem__alloc_8h.html#a4f87c9100d154a65a4ad495f7763cf7c',1,'VmaAllocatorCreateFlagBits(): vk_mem_alloc.h'],['../vk__mem__alloc_8h.html#a4ddf381b6ce795bdfbc6c614640b9915',1,'VmaAllocatorCreateFlagBits(): vk_mem_alloc.h']]],
|
||||
['vmaallocatorcreateflags',['VmaAllocatorCreateFlags',['../vk__mem__alloc_8h.html#acfe6863e160722c2c1bbcf7573fddc4d',1,'vk_mem_alloc.h']]],
|
||||
['vmaallocatorcreateinfo',['VmaAllocatorCreateInfo',['../struct_vma_allocator_create_info.html',1,'VmaAllocatorCreateInfo'],['../vk__mem__alloc_8h.html#ae0f6d1d733dded220d28134da46b4283',1,'VmaAllocatorCreateInfo(): vk_mem_alloc.h']]],
|
||||
['vmabindbuffermemory',['vmaBindBufferMemory',['../vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470',1,'vk_mem_alloc.h']]],
|
||||
['vmabindimagememory',['vmaBindImageMemory',['../vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5',1,'vk_mem_alloc.h']]],
|
||||
['vmabuildstatsstring',['vmaBuildStatsString',['../vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0',1,'vk_mem_alloc.h']]],
|
||||
['vmacalculatestats',['vmaCalculateStats',['../vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3',1,'vk_mem_alloc.h']]],
|
||||
['vmacreateallocator',['vmaCreateAllocator',['../vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb',1,'vk_mem_alloc.h']]],
|
||||
|
@ -3,6 +3,8 @@ var searchData=
|
||||
['vmaallocatememory',['vmaAllocateMemory',['../vk__mem__alloc_8h.html#abf28077dbf82d0908b8acbe8ee8dd9b8',1,'vk_mem_alloc.h']]],
|
||||
['vmaallocatememoryforbuffer',['vmaAllocateMemoryForBuffer',['../vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b',1,'vk_mem_alloc.h']]],
|
||||
['vmaallocatememoryforimage',['vmaAllocateMemoryForImage',['../vk__mem__alloc_8h.html#a0faa3f9e5fb233d29d1e00390650febb',1,'vk_mem_alloc.h']]],
|
||||
['vmabindbuffermemory',['vmaBindBufferMemory',['../vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470',1,'vk_mem_alloc.h']]],
|
||||
['vmabindimagememory',['vmaBindImageMemory',['../vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5',1,'vk_mem_alloc.h']]],
|
||||
['vmabuildstatsstring',['vmaBuildStatsString',['../vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0',1,'vk_mem_alloc.h']]],
|
||||
['vmacalculatestats',['vmaCalculateStats',['../vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3',1,'vk_mem_alloc.h']]],
|
||||
['vmacreateallocator',['vmaCreateAllocator',['../vk__mem__alloc_8h.html#a200692051ddb34240248234f5f4c17bb',1,'vk_mem_alloc.h']]],
|
||||
|
@ -74,9 +74,9 @@ Numeric statistics</h1>
|
||||
<p>You can query for information about specific allocation using function <a class="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>. It fill structure <a class="el" href="struct_vma_allocation_info.html" title="Parameters of VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo(). ">VmaAllocationInfo</a>.</p>
|
||||
<h1><a class="anchor" id="statistics_json_dump"></a>
|
||||
JSON dump</h1>
|
||||
<p>You can dump internal state of the allocator to a string in JSON format using function <a class="el" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0" title="Builds and returns statistics as string in JSON format. ">vmaBuildStatsString()</a>. The result is guaranteed to be correct JSON. It uses ANSI encoding. Any strings provided by user (see <a class="el" href="allocation_annotation.html#allocation_names">Allocation names</a>) are copied as-is and properly escaped for JSON, so if they use UTF-8, ISO-8859-2 or any other encoding, this JSON string can be treted as using this encoding. It must be freed using function <a class="el" href="vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288">vmaFreeStatsString()</a>.</p>
|
||||
<p>The format of this string is not part of official documentation of the library, but it will not change in backward-incompatible way without increasing library major version number and mention in changelog.</p>
|
||||
<p>The string contains all the data that can be obtained using <a class="el" href="vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3" title="Retrieves statistics from current state of the Allocator. ">vmaCalculateStats()</a>. It can also contain detailed map of allocated memory blocks and their regions - free and occupied by allocations. This allows e.g. to visualize the memory or assess fragmentation. </p>
|
||||
<p>You can dump internal state of the allocator to a string in JSON format using function <a class="el" href="vk__mem__alloc_8h.html#aa4fee7eb5253377599ef4fd38c93c2a0" title="Builds and returns statistics as string in JSON format. ">vmaBuildStatsString()</a>. The result is guaranteed to be correct JSON. It uses ANSI encoding. Any strings provided by user (see <a class="el" href="allocation_annotation.html#allocation_names">Allocation names</a>) are copied as-is and properly escaped for JSON, so if they use UTF-8, ISO-8859-2 or any other encoding, this JSON string can be treated as using this encoding. It must be freed using function <a class="el" href="vk__mem__alloc_8h.html#a3104eb30d8122c84dd8541063f145288">vmaFreeStatsString()</a>.</p>
|
||||
<p>The format of this JSON string is not part of official documentation of the library, but it will not change in backward-incompatible way without increasing library major version number and appropriate mention in changelog.</p>
|
||||
<p>The JSON string contains all the data that can be obtained using <a class="el" href="vk__mem__alloc_8h.html#a333b61c1788cb23559177531e6a93ca3" title="Retrieves statistics from current state of the Allocator. ">vmaCalculateStats()</a>. It can also contain detailed map of allocated memory blocks and their regions - free and occupied by allocations. This allows e.g. to visualize the memory or assess fragmentation. </p>
|
||||
</div></div><!-- contents -->
|
||||
<!-- start footer part -->
|
||||
<hr class="footer"/><address class="footer"><small>
|
||||
|
@ -287,6 +287,12 @@ Functions</h2></td></tr>
|
||||
<tr class="memitem:a6aced90fcc7b39882b6654a740a0b9bb"><td class="memItemLeft" align="right" valign="top">VkResult </td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a6aced90fcc7b39882b6654a740a0b9bb">vmaDefragment</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> *pAllocations, size_t allocationCount, VkBool32 *pAllocationsChanged, const <a class="el" href="struct_vma_defragmentation_info.html">VmaDefragmentationInfo</a> *pDefragmentationInfo, <a class="el" href="struct_vma_defragmentation_stats.html">VmaDefragmentationStats</a> *pDefragmentationStats)</td></tr>
|
||||
<tr class="memdesc:a6aced90fcc7b39882b6654a740a0b9bb"><td class="mdescLeft"> </td><td class="mdescRight">Compacts memory by moving allocations. <a href="#a6aced90fcc7b39882b6654a740a0b9bb">More...</a><br /></td></tr>
|
||||
<tr class="separator:a6aced90fcc7b39882b6654a740a0b9bb"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:a6b0929b914b60cf2d45cac4bf3547470"><td class="memItemLeft" align="right" valign="top">VkResult </td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a6b0929b914b60cf2d45cac4bf3547470">vmaBindBufferMemory</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> allocation, VkBuffer buffer)</td></tr>
|
||||
<tr class="memdesc:a6b0929b914b60cf2d45cac4bf3547470"><td class="mdescLeft"> </td><td class="mdescRight">Binds buffer to allocation. <a href="#a6b0929b914b60cf2d45cac4bf3547470">More...</a><br /></td></tr>
|
||||
<tr class="separator:a6b0929b914b60cf2d45cac4bf3547470"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:a3d3ca45799923aa5d138e9e5f9eb2da5"><td class="memItemLeft" align="right" valign="top">VkResult </td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a3d3ca45799923aa5d138e9e5f9eb2da5">vmaBindImageMemory</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> allocation, VkImage image)</td></tr>
|
||||
<tr class="memdesc:a3d3ca45799923aa5d138e9e5f9eb2da5"><td class="mdescLeft"> </td><td class="mdescRight">Binds image to allocation. <a href="#a3d3ca45799923aa5d138e9e5f9eb2da5">More...</a><br /></td></tr>
|
||||
<tr class="separator:a3d3ca45799923aa5d138e9e5f9eb2da5"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:ac72ee55598617e8eecca384e746bab51"><td class="memItemLeft" align="right" valign="top">VkResult </td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, const VkBufferCreateInfo *pBufferCreateInfo, const <a class="el" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> *pAllocationCreateInfo, VkBuffer *pBuffer, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> *pAllocation, <a class="el" href="struct_vma_allocation_info.html">VmaAllocationInfo</a> *pAllocationInfo)</td></tr>
|
||||
<tr class="separator:ac72ee55598617e8eecca384e746bab51"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:a0d9f4e4ba5bf9aab1f1c746387753d77"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="vk__mem__alloc_8h.html#a0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a> (<a class="el" href="struct_vma_allocator.html">VmaAllocator</a> allocator, VkBuffer buffer, <a class="el" href="struct_vma_allocation.html">VmaAllocation</a> allocation)</td></tr>
|
||||
@ -929,6 +935,82 @@ Functions</h2></td></tr>
|
||||
|
||||
<p>Function similar to <a class="el" href="vk__mem__alloc_8h.html#a7fdf64415b6c3d83c454f28d2c53df7b">vmaAllocateMemoryForBuffer()</a>. </p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<a id="a6b0929b914b60cf2d45cac4bf3547470"></a>
|
||||
<h2 class="memtitle"><span class="permalink"><a href="#a6b0929b914b60cf2d45cac4bf3547470">◆ </a></span>vmaBindBufferMemory()</h2>
|
||||
|
||||
<div class="memitem">
|
||||
<div class="memproto">
|
||||
<table class="memname">
|
||||
<tr>
|
||||
<td class="memname">VkResult vmaBindBufferMemory </td>
|
||||
<td>(</td>
|
||||
<td class="paramtype"><a class="el" href="struct_vma_allocator.html">VmaAllocator</a> </td>
|
||||
<td class="paramname"><em>allocator</em>, </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="paramkey"></td>
|
||||
<td></td>
|
||||
<td class="paramtype"><a class="el" href="struct_vma_allocation.html">VmaAllocation</a> </td>
|
||||
<td class="paramname"><em>allocation</em>, </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="paramkey"></td>
|
||||
<td></td>
|
||||
<td class="paramtype">VkBuffer </td>
|
||||
<td class="paramname"><em>buffer</em> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>)</td>
|
||||
<td></td><td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div><div class="memdoc">
|
||||
|
||||
<p>Binds buffer to allocation. </p>
|
||||
<p>Binds specified buffer to region of memory represented by specified allocation. Gets <code>VkDeviceMemory</code> handle and offset from the allocation. If you want to create a buffer, allocate memory for it and bind them together separately, you should use this function for binding instead of standard <code>vkBindBufferMemory()</code>, because it ensures proper synchronization so that when a <code>VkDeviceMemory</code> object is used by multiple allocations, calls to <code>vkBind*Memory()</code> or <code>vkMapMemory()</code> won't happen from multiple threads simultaneously (which is illegal in Vulkan).</p>
|
||||
<p>It is recommended to use function <a class="el" href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer()</a> instead of this one. </p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<a id="a3d3ca45799923aa5d138e9e5f9eb2da5"></a>
|
||||
<h2 class="memtitle"><span class="permalink"><a href="#a3d3ca45799923aa5d138e9e5f9eb2da5">◆ </a></span>vmaBindImageMemory()</h2>
|
||||
|
||||
<div class="memitem">
|
||||
<div class="memproto">
|
||||
<table class="memname">
|
||||
<tr>
|
||||
<td class="memname">VkResult vmaBindImageMemory </td>
|
||||
<td>(</td>
|
||||
<td class="paramtype"><a class="el" href="struct_vma_allocator.html">VmaAllocator</a> </td>
|
||||
<td class="paramname"><em>allocator</em>, </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="paramkey"></td>
|
||||
<td></td>
|
||||
<td class="paramtype"><a class="el" href="struct_vma_allocation.html">VmaAllocation</a> </td>
|
||||
<td class="paramname"><em>allocation</em>, </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="paramkey"></td>
|
||||
<td></td>
|
||||
<td class="paramtype">VkImage </td>
|
||||
<td class="paramname"><em>image</em> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>)</td>
|
||||
<td></td><td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div><div class="memdoc">
|
||||
|
||||
<p>Binds image to allocation. </p>
|
||||
<p>Binds specified image to region of memory represented by specified allocation. Gets <code>VkDeviceMemory</code> handle and offset from the allocation. If you want to create an image, allocate memory for it and bind them together separately, you should use this function for binding instead of standard <code>vkBindImageMemory()</code>, because it ensures proper synchronization so that when a <code>VkDeviceMemory</code> object is used by multiple allocations, calls to <code>vkBind*Memory()</code> or <code>vkMapMemory()</code> won't happen from multiple threads simultaneously (which is illegal in Vulkan).</p>
|
||||
<p>It is recommended to use function <a class="el" href="vk__mem__alloc_8h.html#a02a94f25679275851a53e82eacbcfc73" title="Function similar to vmaCreateBuffer(). ">vmaCreateImage()</a> instead of this one. </p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<a id="aa4fee7eb5253377599ef4fd38c93c2a0"></a>
|
||||
|
File diff suppressed because one or more lines are too long
@ -175,6 +175,7 @@ You can also combine multiple methods.
|
||||
-# If you already have a buffer or an image created, you want to allocate memory
|
||||
for it and then you will bind it yourself, you can use function
|
||||
vmaAllocateMemoryForBuffer(), vmaAllocateMemoryForImage().
|
||||
For binding you should use functions: vmaBindBufferMemory(), vmaBindImageMemory().
|
||||
-# If you want to create a buffer or an image, allocate memory for it and bind
|
||||
them together, all in one call, you can use function vmaCreateBuffer(),
|
||||
vmaCreateImage(). This is the recommended way to use this library.
|
||||
@ -715,14 +716,14 @@ The result is guaranteed to be correct JSON.
|
||||
It uses ANSI encoding.
|
||||
Any strings provided by user (see [Allocation names](@ref allocation_names))
|
||||
are copied as-is and properly escaped for JSON, so if they use UTF-8, ISO-8859-2 or any other encoding,
|
||||
this JSON string can be treted as using this encoding.
|
||||
this JSON string can be treated as using this encoding.
|
||||
It must be freed using function vmaFreeStatsString().
|
||||
|
||||
The format of this string is not part of official documentation of the library,
|
||||
The format of this JSON string is not part of official documentation of the library,
|
||||
but it will not change in backward-incompatible way without increasing library major version number
|
||||
and mention in changelog.
|
||||
and appropriate mention in changelog.
|
||||
|
||||
The string contains all the data that can be obtained using vmaCalculateStats().
|
||||
The JSON string contains all the data that can be obtained using vmaCalculateStats().
|
||||
It can also contain detailed map of allocated memory blocks and their regions -
|
||||
free and occupied by allocations.
|
||||
This allows e.g. to visualize the memory or assess fragmentation.
|
||||
@ -2045,6 +2046,40 @@ VkResult vmaDefragment(
|
||||
const VmaDefragmentationInfo *pDefragmentationInfo,
|
||||
VmaDefragmentationStats* pDefragmentationStats);
|
||||
|
||||
/** \brief Binds buffer to allocation.
|
||||
|
||||
Binds specified buffer to region of memory represented by specified allocation.
|
||||
Gets `VkDeviceMemory` handle and offset from the allocation.
|
||||
If you want to create a buffer, allocate memory for it and bind them together separately,
|
||||
you should use this function for binding instead of standard `vkBindBufferMemory()`,
|
||||
because it ensures proper synchronization so that when a `VkDeviceMemory` object is used by multiple
|
||||
allocations, calls to `vkBind*Memory()` or `vkMapMemory()` won't happen from multiple threads simultaneously
|
||||
(which is illegal in Vulkan).
|
||||
|
||||
It is recommended to use function vmaCreateBuffer() instead of this one.
|
||||
*/
|
||||
VkResult vmaBindBufferMemory(
|
||||
VmaAllocator allocator,
|
||||
VmaAllocation allocation,
|
||||
VkBuffer buffer);
|
||||
|
||||
/** \brief Binds image to allocation.
|
||||
|
||||
Binds specified image to region of memory represented by specified allocation.
|
||||
Gets `VkDeviceMemory` handle and offset from the allocation.
|
||||
If you want to create an image, allocate memory for it and bind them together separately,
|
||||
you should use this function for binding instead of standard `vkBindImageMemory()`,
|
||||
because it ensures proper synchronization so that when a `VkDeviceMemory` object is used by multiple
|
||||
allocations, calls to `vkBind*Memory()` or `vkMapMemory()` won't happen from multiple threads simultaneously
|
||||
(which is illegal in Vulkan).
|
||||
|
||||
It is recommended to use function vmaCreateImage() instead of this one.
|
||||
*/
|
||||
VkResult vmaBindImageMemory(
|
||||
VmaAllocator allocator,
|
||||
VmaAllocation allocation,
|
||||
VkImage image);
|
||||
|
||||
/**
|
||||
@param[out] pBuffer Buffer that was created.
|
||||
@param[out] pAllocation Allocation that was created.
|
||||
@ -4029,25 +4064,6 @@ private:
|
||||
void UnregisterFreeSuballocation(VmaSuballocationList::iterator item);
|
||||
};
|
||||
|
||||
// Helper class that represents mapped memory. Synchronized internally.
|
||||
class VmaDeviceMemoryMapping
|
||||
{
|
||||
public:
|
||||
VmaDeviceMemoryMapping();
|
||||
~VmaDeviceMemoryMapping();
|
||||
|
||||
void* GetMappedData() const { return m_pMappedData; }
|
||||
|
||||
// ppData can be null.
|
||||
VkResult Map(VmaAllocator hAllocator, VkDeviceMemory hMemory, uint32_t count, void **ppData);
|
||||
void Unmap(VmaAllocator hAllocator, VkDeviceMemory hMemory, uint32_t count);
|
||||
|
||||
private:
|
||||
VMA_MUTEX m_Mutex;
|
||||
uint32_t m_MapCount;
|
||||
void* m_pMappedData;
|
||||
};
|
||||
|
||||
/*
|
||||
Represents a single block of device memory (`VkDeviceMemory`) with all the
|
||||
data about its regions (aka suballocations, #VmaAllocation), assigned and free.
|
||||
@ -4057,15 +4073,13 @@ Thread-safety: This class must be externally synchronized.
|
||||
class VmaDeviceMemoryBlock
|
||||
{
|
||||
public:
|
||||
uint32_t m_MemoryTypeIndex;
|
||||
VkDeviceMemory m_hMemory;
|
||||
VmaDeviceMemoryMapping m_Mapping;
|
||||
VmaBlockMetadata m_Metadata;
|
||||
|
||||
VmaDeviceMemoryBlock(VmaAllocator hAllocator);
|
||||
|
||||
~VmaDeviceMemoryBlock()
|
||||
{
|
||||
VMA_ASSERT(m_MapCount == 0 && "VkDeviceMemory block is being destroyed while it is still mapped.");
|
||||
VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);
|
||||
}
|
||||
|
||||
@ -4077,12 +4091,35 @@ public:
|
||||
// Always call before destruction.
|
||||
void Destroy(VmaAllocator allocator);
|
||||
|
||||
VkDeviceMemory GetDeviceMemory() const { return m_hMemory; }
|
||||
uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; }
|
||||
void* GetMappedData() const { return m_pMappedData; }
|
||||
|
||||
// Validates all data structures inside this object. If not valid, returns false.
|
||||
bool Validate() const;
|
||||
|
||||
// ppData can be null.
|
||||
VkResult Map(VmaAllocator hAllocator, uint32_t count, void** ppData);
|
||||
void Unmap(VmaAllocator hAllocator, uint32_t count);
|
||||
|
||||
VkResult BindBufferMemory(
|
||||
const VmaAllocator hAllocator,
|
||||
const VmaAllocation hAllocation,
|
||||
VkBuffer hBuffer);
|
||||
VkResult BindImageMemory(
|
||||
const VmaAllocator hAllocator,
|
||||
const VmaAllocation hAllocation,
|
||||
VkImage hImage);
|
||||
|
||||
private:
|
||||
uint32_t m_MemoryTypeIndex;
|
||||
VkDeviceMemory m_hMemory;
|
||||
|
||||
// Protects access to m_hMemory so it's not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory.
|
||||
// Also protects m_MapCount, m_pMappedData.
|
||||
VMA_MUTEX m_Mutex;
|
||||
uint32_t m_MapCount;
|
||||
void* m_pMappedData;
|
||||
};
|
||||
|
||||
struct VmaPointerLess
|
||||
@ -4448,6 +4485,9 @@ struct VmaAllocator_T
|
||||
VkResult Map(VmaAllocation hAllocation, void** ppData);
|
||||
void Unmap(VmaAllocation hAllocation);
|
||||
|
||||
VkResult BindBufferMemory(VmaAllocation hAllocation, VkBuffer hBuffer);
|
||||
VkResult BindImageMemory(VmaAllocation hAllocation, VkImage hImage);
|
||||
|
||||
private:
|
||||
VkDeviceSize m_PreferredLargeHeapBlockSize;
|
||||
|
||||
@ -4946,7 +4986,7 @@ VkDeviceMemory VmaAllocation_T::GetMemory() const
|
||||
switch(m_Type)
|
||||
{
|
||||
case ALLOCATION_TYPE_BLOCK:
|
||||
return m_BlockAllocation.m_Block->m_hMemory;
|
||||
return m_BlockAllocation.m_Block->GetDeviceMemory();
|
||||
case ALLOCATION_TYPE_DEDICATED:
|
||||
return m_DedicatedAllocation.m_hMemory;
|
||||
default:
|
||||
@ -4960,7 +5000,7 @@ uint32_t VmaAllocation_T::GetMemoryTypeIndex() const
|
||||
switch(m_Type)
|
||||
{
|
||||
case ALLOCATION_TYPE_BLOCK:
|
||||
return m_BlockAllocation.m_Block->m_MemoryTypeIndex;
|
||||
return m_BlockAllocation.m_Block->GetMemoryTypeIndex();
|
||||
case ALLOCATION_TYPE_DEDICATED:
|
||||
return m_DedicatedAllocation.m_MemoryTypeIndex;
|
||||
default:
|
||||
@ -4976,7 +5016,7 @@ void* VmaAllocation_T::GetMappedData() const
|
||||
case ALLOCATION_TYPE_BLOCK:
|
||||
if(m_MapCount != 0)
|
||||
{
|
||||
void* pBlockData = m_BlockAllocation.m_Block->m_Mapping.GetMappedData();
|
||||
void* pBlockData = m_BlockAllocation.m_Block->GetMappedData();
|
||||
VMA_ASSERT(pBlockData != VMA_NULL);
|
||||
return (char*)pBlockData + m_BlockAllocation.m_Offset;
|
||||
}
|
||||
@ -6219,89 +6259,15 @@ void VmaBlockMetadata::UnregisterFreeSuballocation(VmaSuballocationList::iterato
|
||||
//VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class VmaDeviceMemoryMapping
|
||||
|
||||
VmaDeviceMemoryMapping::VmaDeviceMemoryMapping() :
|
||||
m_MapCount(0),
|
||||
m_pMappedData(VMA_NULL)
|
||||
{
|
||||
}
|
||||
|
||||
VmaDeviceMemoryMapping::~VmaDeviceMemoryMapping()
|
||||
{
|
||||
VMA_ASSERT(m_MapCount == 0 && "VkDeviceMemory block is being destroyed while it is still mapped.");
|
||||
}
|
||||
|
||||
VkResult VmaDeviceMemoryMapping::Map(VmaAllocator hAllocator, VkDeviceMemory hMemory, uint32_t count, void **ppData)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VmaMutexLock lock(m_Mutex, hAllocator->m_UseMutex);
|
||||
if(m_MapCount != 0)
|
||||
{
|
||||
m_MapCount += count;
|
||||
VMA_ASSERT(m_pMappedData != VMA_NULL);
|
||||
if(ppData != VMA_NULL)
|
||||
{
|
||||
*ppData = m_pMappedData;
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
VkResult result = (*hAllocator->GetVulkanFunctions().vkMapMemory)(
|
||||
hAllocator->m_hDevice,
|
||||
hMemory,
|
||||
0, // offset
|
||||
VK_WHOLE_SIZE,
|
||||
0, // flags
|
||||
&m_pMappedData);
|
||||
if(result == VK_SUCCESS)
|
||||
{
|
||||
if(ppData != VMA_NULL)
|
||||
{
|
||||
*ppData = m_pMappedData;
|
||||
}
|
||||
m_MapCount = count;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void VmaDeviceMemoryMapping::Unmap(VmaAllocator hAllocator, VkDeviceMemory hMemory, uint32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VmaMutexLock lock(m_Mutex, hAllocator->m_UseMutex);
|
||||
if(m_MapCount >= count)
|
||||
{
|
||||
m_MapCount -= count;
|
||||
if(m_MapCount == 0)
|
||||
{
|
||||
m_pMappedData = VMA_NULL;
|
||||
(*hAllocator->GetVulkanFunctions().vkUnmapMemory)(hAllocator->m_hDevice, hMemory);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VMA_ASSERT(0 && "VkDeviceMemory block is being unmapped while it was not previously mapped.");
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class VmaDeviceMemoryBlock
|
||||
|
||||
VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator) :
|
||||
m_Metadata(hAllocator),
|
||||
m_MemoryTypeIndex(UINT32_MAX),
|
||||
m_hMemory(VK_NULL_HANDLE),
|
||||
m_Metadata(hAllocator)
|
||||
m_MapCount(0),
|
||||
m_pMappedData(VMA_NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -6342,12 +6308,96 @@ bool VmaDeviceMemoryBlock::Validate() const
|
||||
|
||||
VkResult VmaDeviceMemoryBlock::Map(VmaAllocator hAllocator, uint32_t count, void** ppData)
|
||||
{
|
||||
return m_Mapping.Map(hAllocator, m_hMemory, count, ppData);
|
||||
if(count == 0)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VmaMutexLock lock(m_Mutex, hAllocator->m_UseMutex);
|
||||
if(m_MapCount != 0)
|
||||
{
|
||||
m_MapCount += count;
|
||||
VMA_ASSERT(m_pMappedData != VMA_NULL);
|
||||
if(ppData != VMA_NULL)
|
||||
{
|
||||
*ppData = m_pMappedData;
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
VkResult result = (*hAllocator->GetVulkanFunctions().vkMapMemory)(
|
||||
hAllocator->m_hDevice,
|
||||
m_hMemory,
|
||||
0, // offset
|
||||
VK_WHOLE_SIZE,
|
||||
0, // flags
|
||||
&m_pMappedData);
|
||||
if(result == VK_SUCCESS)
|
||||
{
|
||||
if(ppData != VMA_NULL)
|
||||
{
|
||||
*ppData = m_pMappedData;
|
||||
}
|
||||
m_MapCount = count;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void VmaDeviceMemoryBlock::Unmap(VmaAllocator hAllocator, uint32_t count)
|
||||
{
|
||||
m_Mapping.Unmap(hAllocator, m_hMemory, count);
|
||||
if(count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VmaMutexLock lock(m_Mutex, hAllocator->m_UseMutex);
|
||||
if(m_MapCount >= count)
|
||||
{
|
||||
m_MapCount -= count;
|
||||
if(m_MapCount == 0)
|
||||
{
|
||||
m_pMappedData = VMA_NULL;
|
||||
(*hAllocator->GetVulkanFunctions().vkUnmapMemory)(hAllocator->m_hDevice, m_hMemory);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VMA_ASSERT(0 && "VkDeviceMemory block is being unmapped while it was not previously mapped.");
|
||||
}
|
||||
}
|
||||
|
||||
VkResult VmaDeviceMemoryBlock::BindBufferMemory(
|
||||
const VmaAllocator hAllocator,
|
||||
const VmaAllocation hAllocation,
|
||||
VkBuffer hBuffer)
|
||||
{
|
||||
VMA_ASSERT(hAllocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK &&
|
||||
hAllocation->GetBlock() == this);
|
||||
// This lock is important so that we don't call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads.
|
||||
VmaMutexLock lock(m_Mutex, hAllocator->m_UseMutex);
|
||||
return hAllocator->GetVulkanFunctions().vkBindBufferMemory(
|
||||
hAllocator->m_hDevice,
|
||||
hBuffer,
|
||||
m_hMemory,
|
||||
hAllocation->GetOffset());
|
||||
}
|
||||
|
||||
VkResult VmaDeviceMemoryBlock::BindImageMemory(
|
||||
const VmaAllocator hAllocator,
|
||||
const VmaAllocation hAllocation,
|
||||
VkImage hImage)
|
||||
{
|
||||
VMA_ASSERT(hAllocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK &&
|
||||
hAllocation->GetBlock() == this);
|
||||
// This lock is important so that we don't call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads.
|
||||
VmaMutexLock lock(m_Mutex, hAllocator->m_UseMutex);
|
||||
return hAllocator->GetVulkanFunctions().vkBindImageMemory(
|
||||
hAllocator->m_hDevice,
|
||||
hImage,
|
||||
m_hMemory,
|
||||
hAllocation->GetOffset());
|
||||
}
|
||||
|
||||
static void InitStatInfo(VmaStatInfo& outInfo)
|
||||
@ -6741,7 +6791,7 @@ void VmaBlockVector::Free(
|
||||
|
||||
if(hAllocation->IsPersistentMap())
|
||||
{
|
||||
pBlock->m_Mapping.Unmap(m_hAllocator, pBlock->m_hMemory, 1);
|
||||
pBlock->Unmap(m_hAllocator, 1);
|
||||
}
|
||||
|
||||
pBlock->m_Metadata.Free(hAllocation);
|
||||
@ -7079,9 +7129,9 @@ VkResult VmaDefragmentator::BlockInfo::EnsureMapping(VmaAllocator hAllocator, vo
|
||||
}
|
||||
|
||||
// It is originally mapped.
|
||||
if(m_pBlock->m_Mapping.GetMappedData())
|
||||
if(m_pBlock->GetMappedData())
|
||||
{
|
||||
*ppMappedData = m_pBlock->m_Mapping.GetMappedData();
|
||||
*ppMappedData = m_pBlock->GetMappedData();
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
@ -8304,6 +8354,56 @@ void VmaAllocator_T::Unmap(VmaAllocation hAllocation)
|
||||
}
|
||||
}
|
||||
|
||||
VkResult VmaAllocator_T::BindBufferMemory(VmaAllocation hAllocation, VkBuffer hBuffer)
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
switch(hAllocation->GetType())
|
||||
{
|
||||
case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
|
||||
res = GetVulkanFunctions().vkBindBufferMemory(
|
||||
m_hDevice,
|
||||
hBuffer,
|
||||
hAllocation->GetMemory(),
|
||||
0); //memoryOffset
|
||||
break;
|
||||
case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
|
||||
{
|
||||
VmaDeviceMemoryBlock* pBlock = hAllocation->GetBlock();
|
||||
VMA_ASSERT(pBlock && "Binding buffer to allocation that doesn't belong to any block. Is the allocation lost?");
|
||||
res = pBlock->BindBufferMemory(this, hAllocation, hBuffer);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
VMA_ASSERT(0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
VkResult VmaAllocator_T::BindImageMemory(VmaAllocation hAllocation, VkImage hImage)
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
switch(hAllocation->GetType())
|
||||
{
|
||||
case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
|
||||
res = GetVulkanFunctions().vkBindImageMemory(
|
||||
m_hDevice,
|
||||
hImage,
|
||||
hAllocation->GetMemory(),
|
||||
0); //memoryOffset
|
||||
break;
|
||||
case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
|
||||
{
|
||||
VmaDeviceMemoryBlock* pBlock = hAllocation->GetBlock();
|
||||
VMA_ASSERT(pBlock && "Binding image to allocation that doesn't belong to any block. Is the allocation lost?");
|
||||
res = pBlock->BindImageMemory(this, hAllocation, hImage);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
VMA_ASSERT(0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void VmaAllocator_T::FreeDedicatedMemory(VmaAllocation allocation)
|
||||
{
|
||||
VMA_ASSERT(allocation && allocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED);
|
||||
@ -9051,6 +9151,34 @@ VkResult vmaDefragment(
|
||||
return allocator->Defragment(pAllocations, allocationCount, pAllocationsChanged, pDefragmentationInfo, pDefragmentationStats);
|
||||
}
|
||||
|
||||
VkResult vmaBindBufferMemory(
|
||||
VmaAllocator allocator,
|
||||
VmaAllocation allocation,
|
||||
VkBuffer buffer)
|
||||
{
|
||||
VMA_ASSERT(allocator && allocation && buffer);
|
||||
|
||||
VMA_DEBUG_LOG("vmaBindBufferMemory");
|
||||
|
||||
VMA_DEBUG_GLOBAL_MUTEX_LOCK
|
||||
|
||||
return allocator->BindBufferMemory(allocation, buffer);
|
||||
}
|
||||
|
||||
VkResult vmaBindImageMemory(
|
||||
VmaAllocator allocator,
|
||||
VmaAllocation allocation,
|
||||
VkImage image)
|
||||
{
|
||||
VMA_ASSERT(allocator && allocation && image);
|
||||
|
||||
VMA_DEBUG_LOG("vmaBindImageMemory");
|
||||
|
||||
VMA_DEBUG_GLOBAL_MUTEX_LOCK
|
||||
|
||||
return allocator->BindImageMemory(allocation, image);
|
||||
}
|
||||
|
||||
VkResult vmaCreateBuffer(
|
||||
VmaAllocator allocator,
|
||||
const VkBufferCreateInfo* pBufferCreateInfo,
|
||||
@ -9114,11 +9242,7 @@ VkResult vmaCreateBuffer(
|
||||
if(res >= 0)
|
||||
{
|
||||
// 3. Bind buffer with memory.
|
||||
res = (*allocator->GetVulkanFunctions().vkBindBufferMemory)(
|
||||
allocator->m_hDevice,
|
||||
*pBuffer,
|
||||
(*pAllocation)->GetMemory(),
|
||||
(*pAllocation)->GetOffset());
|
||||
res = allocator->BindBufferMemory(*pAllocation, *pBuffer);
|
||||
if(res >= 0)
|
||||
{
|
||||
// All steps succeeded.
|
||||
@ -9194,11 +9318,7 @@ VkResult vmaCreateImage(
|
||||
if(res >= 0)
|
||||
{
|
||||
// 3. Bind image with memory.
|
||||
res = (*allocator->GetVulkanFunctions().vkBindImageMemory)(
|
||||
allocator->m_hDevice,
|
||||
*pImage,
|
||||
(*pAllocation)->GetMemory(),
|
||||
(*pAllocation)->GetOffset());
|
||||
res = allocator->BindImageMemory(*pAllocation, *pImage);
|
||||
if(res >= 0)
|
||||
{
|
||||
// All steps succeeded.
|
||||
|
Loading…
Reference in New Issue
Block a user