mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
synced 2024-11-24 21:10:12 +00:00
Written more documentation.
This commit is contained in:
parent
359793763a
commit
95451ab2a6
@ -87,7 +87,7 @@ Cache control</h1>
|
||||
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 <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"></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, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);</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>, &memFlags);</div><div class="line"><span class="keywordflow">if</span>((memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)</div><div class="line">{</div><div class="line"> <span class="comment">// Allocation ended up in mappable memory. You can map it and access it directly.</span></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, alloc, &mappedData);</div><div class="line"> memcpy(mappedData, &constantBufferData, <span class="keyword">sizeof</span>(constantBufferData));</div><div class="line"> <a class="code" href="vk__mem__alloc_8h.html#a9bc268595cb33f6ec4d519cfce81ff45">vmaUnmapMemory</a>(allocator, alloc);</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 --><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, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &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'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>, &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>
|
||||
|
@ -66,14 +66,17 @@ $(function() {
|
||||
<div class="title">Quick start </div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
<div class="textblock"><h1><a class="anchor" id="project_setup"></a>
|
||||
<div class="textblock"><h1><a class="anchor" id="quick_start_project_setup"></a>
|
||||
Project setup</h1>
|
||||
<p>In your project code:</p>
|
||||
<p>Vulkan Memory Allocator comes in form of a single header file. You don't need to build it as a separate library project. You can add this file directly to your project and submit it to code repository next to your other source files.</p>
|
||||
<p>"Single header" doesn't mean that everything is contained in C/C++ declarations, like it tends to be in case of inline functions or C++ templates. It means that implementation is bundled with interface in a single file and needs to be extracted using preprocessor macro. If you don't do it properly, you will get linker errors.</p>
|
||||
<p>To do it properly:</p>
|
||||
<ol type="1">
|
||||
<li>Include "vk_mem_alloc.h" file wherever you want to use the library.</li>
|
||||
<li>In exacly one C++ file define following macro before include to build library implementation.</li>
|
||||
<li>Include "vk_mem_alloc.h" file in each CPP file where you want to use the library. This includes declarations of all members of the library.</li>
|
||||
<li>In exacly one CPP file define following macro before this include. It enables also internal definitions.</li>
|
||||
</ol>
|
||||
<div class="fragment"><div class="line"><span class="preprocessor">#define VMA_IMPLEMENTATION</span></div><div class="line"><span class="preprocessor">#include "vk_mem_alloc.h"</span></div></div><!-- fragment --><h1><a class="anchor" id="initialization"></a>
|
||||
<div class="fragment"><div class="line"><span class="preprocessor">#define VMA_IMPLEMENTATION</span></div><div class="line"><span class="preprocessor">#include "vk_mem_alloc.h"</span></div></div><!-- fragment --><p>It may be a good idea to create dedicated CPP file just for this purpose.</p>
|
||||
<h1><a class="anchor" id="initialization"></a>
|
||||
Initialization</h1>
|
||||
<p>At program startup:</p>
|
||||
<ol type="1">
|
||||
|
File diff suppressed because one or more lines are too long
@ -61,19 +61,31 @@ See also:
|
||||
|
||||
\page quick_start Quick start
|
||||
|
||||
\section project_setup Project setup
|
||||
\section quick_start_project_setup Project setup
|
||||
|
||||
In your project code:
|
||||
Vulkan Memory Allocator comes in form of a single header file.
|
||||
You don't need to build it as a separate library project.
|
||||
You can add this file directly to your project and submit it to code repository next to your other source files.
|
||||
|
||||
-# Include "vk_mem_alloc.h" file wherever you want to use the library.
|
||||
-# In exacly one C++ file define following macro before include to build library
|
||||
implementation.
|
||||
"Single header" doesn't mean that everything is contained in C/C++ declarations,
|
||||
like it tends to be in case of inline functions or C++ templates.
|
||||
It means that implementation is bundled with interface in a single file and needs to be extracted using preprocessor macro.
|
||||
If you don't do it properly, you will get linker errors.
|
||||
|
||||
To do it properly:
|
||||
|
||||
-# Include "vk_mem_alloc.h" file in each CPP file where you want to use the library.
|
||||
This includes declarations of all members of the library.
|
||||
-# In exacly one CPP file define following macro before this include.
|
||||
It enables also internal definitions.
|
||||
|
||||
\code
|
||||
#define VMA_IMPLEMENTATION
|
||||
#include "vk_mem_alloc.h"
|
||||
\endcode
|
||||
|
||||
It may be a good idea to create dedicated CPP file just for this purpose.
|
||||
|
||||
\section initialization Initialization
|
||||
|
||||
At program startup:
|
||||
@ -365,6 +377,36 @@ 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.
|
||||
|
||||
\code
|
||||
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
bufCreateInfo.size = sizeof(ConstantBuffer);
|
||||
bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
VmaAllocationCreateInfo allocCreateInfo = {};
|
||||
allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
|
||||
|
||||
VkBuffer buf;
|
||||
VmaAllocation alloc;
|
||||
VmaAllocationInfo allocInfo;
|
||||
vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
|
||||
|
||||
VkMemoryPropertyFlags memFlags;
|
||||
vmaGetMemoryTypeProperties(allocator, allocInfo.memoryType, &memFlags);
|
||||
if((memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)
|
||||
{
|
||||
// Allocation ended up in mappable memory. You can map it and access it directly.
|
||||
void* mappedData;
|
||||
vmaMapMemory(allocator, alloc, &mappedData);
|
||||
memcpy(mappedData, &constantBufferData, sizeof(constantBufferData));
|
||||
vmaUnmapMemory(allocator, alloc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allocation ended up in non-mappable memory.
|
||||
// You need to create CPU-side buffer in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer.
|
||||
}
|
||||
\endcode
|
||||
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user