blob: 1d3899d4e9576e4711586b005467ee4006b768a5 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.14.0"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Vulkan Memory Allocator: Interop with other graphics APIs</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">Vulkan Memory Allocator
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.14.0 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search/",'.html');
</script>
<script type="text/javascript">
$(function() { codefold.init(); });
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
initMenu('',true,false,'search.php','Search',false);
$(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a href="index.html">Vulkan Memory Allocator</a></li> </ul>
</div>
</div><!-- top -->
<div id="doc-content">
<div><div class="header">
<div class="headertitle"><div class="title">Interop with other graphics APIs </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>VMA provides some features that help with interoperability with other graphics APIs, e.g. OpenGL, Direct3D 11, Direct3D 12.</p>
<h1 class="doxsection"><a class="anchor" id="other_api_interop_exporting_memory"></a>
Exporting memory</h1>
<p>On Windows, the VK_KHR_external_memory_win32 device extension allows exporting a Win32 <span class="tt">HANDLE</span> of a <span class="tt">VkDeviceMemory</span> block, to be able to reference the memory on other Vulkan logical devices or instances, in multiple processes, and/or in multiple APIs. VMA offers support for it.</p>
<h2 class="doxsection"><a class="anchor" id="other_api_interop_exporting_initialization"></a>
Initialization</h2>
<p>1) Make sure the extension is defined in the code by including following header before including VMA:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;vulkan/vulkan_win32.h&gt;</span></div>
</div><!-- fragment --><p>2) Check if "VK_KHR_external_memory_win32" is available among device extensions. Enable it when creating the <span class="tt">VkDevice</span> object.</p>
<p>3) Enable the usage of this extension in VMA by setting flag <a class="el" href="group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca4897d1181a186e327f4dadd680ad00ac">VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT</a> when calling <a class="el" href="group__group__init.html#ga200692051ddb34240248234f5f4c17bb" title="Creates VmaAllocator object.">vmaCreateAllocator()</a>.</p>
<p>4) Make sure that VMA has access to the <span class="tt">vkGetMemoryWin32HandleKHR</span> function by either enabling <span class="tt">VMA_DYNAMIC_VULKAN_FUNCTIONS</span> macro or setting <a class="el" href="struct_vma_vulkan_functions.html#af45d10a2b47971f4cf5bcacf1d331f86">VmaVulkanFunctions::vkGetMemoryWin32HandleKHR</a> explicitly. For more information, see <a class="el" href="quick_start.html#quick_start_initialization_importing_vulkan_functions">Importing Vulkan functions</a>.</p>
<h2 class="doxsection"><a class="anchor" id="other_api_interop_exporting_preparations"></a>
Preparations</h2>
<p>You can find example usage among tests, in file "Tests.cpp", function <span class="tt">TestWin32Handles()</span>.</p>
<p>To use the extenion, buffers need to be created with <span class="tt">VkExternalMemoryBufferCreateInfoKHR</span> attached to their <span class="tt">pNext</span> chain, and memory allocations need to be made with <span class="tt">VkExportMemoryAllocateInfoKHR</span> attached to their <span class="tt">pNext</span> chain. To make use of them, you need to use <a class="el" href="custom_memory_pools.html">Custom memory pools</a>. Example:</p>
<div class="fragment"><div class="line"><span class="keyword">constexpr</span> VkExternalMemoryHandleTypeFlagsKHR handleType =</div>
<div class="line"> VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Define an example buffer and allocation parameters.</span></div>
<div class="line">VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {</div>
<div class="line"> VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,</div>
<div class="line"> <span class="keyword">nullptr</span>,</div>
<div class="line"> handleType</div>
<div class="line">};</div>
<div class="line">VkBufferCreateInfo exampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div>
<div class="line">exampleBufCreateInfo.size = 0x10000; <span class="comment">// Doesn&#39;t matter here.</span></div>
<div class="line">exampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div>
<div class="line">exampleBufCreateInfo.pNext = &amp;externalMemBufCreateInfo;</div>
<div class="line"> </div>
<div class="line"><a class="code hl_struct" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> exampleAllocCreateInfo = {};</div>
<div class="line">exampleAllocCreateInfo.<a class="code hl_variable" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code hl_enumvalue" href="group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca27cde9026a84d34d525777baa41fce6e">VMA_MEMORY_USAGE_AUTO</a>;</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Find memory type index to use for the custom pool.</span></div>
<div class="line">uint32_t memTypeIndex;</div>
<div class="line">VkResult res = <a class="code hl_function" href="group__group__alloc.html#gae790ab9ffaf7667fb8f62523e6897888">vmaFindMemoryTypeIndexForBufferInfo</a>(g_Allocator,</div>
<div class="line"> &amp;exampleBufCreateInfo, &amp;exampleAllocCreateInfo, &amp;memTypeIndex);</div>
<div class="line"><span class="comment">// Check res...</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// Create a custom pool.</span></div>
<div class="line"><span class="keyword">constexpr</span> <span class="keyword">static</span> VkExportMemoryAllocateInfoKHR exportMemAllocInfo = {</div>
<div class="line"> VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,</div>
<div class="line"> <span class="keyword">nullptr</span>,</div>
<div class="line"> handleType</div>
<div class="line">};</div>
<div class="line"><a class="code hl_struct" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a> poolCreateInfo = {};</div>
<div class="line">poolCreateInfo.<a class="code hl_variable" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a> = memTypeIndex;</div>
<div class="line">poolCreateInfo.<a class="code hl_variable" href="struct_vma_pool_create_info.html#ab6f2e52c47bfe1f4b44920b8bfc27b41">pMemoryAllocateNext</a> = (<span class="keywordtype">void</span>*)&amp;exportMemAllocInfo;</div>
<div class="line"> </div>
<div class="line"><a class="code hl_struct" href="struct_vma_pool.html">VmaPool</a> pool;</div>
<div class="line">res = <a class="code hl_function" href="group__group__alloc.html#ga5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a>(g_Allocator, &amp;poolCreateInfo, &amp;pool);</div>
<div class="line"><span class="comment">// Check res...</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// YOUR OTHER CODE COMES HERE....</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// At the end, don&#39;t forget to destroy it!</span></div>
<div class="line"><a class="code hl_function" href="group__group__alloc.html#ga5485779c8f1948238fc4e92232fa65e1">vmaDestroyPool</a>(g_Allocator, pool);</div>
<div class="ttc" id="agroup__group__alloc_html_ga5485779c8f1948238fc4e92232fa65e1"><div class="ttname"><a href="group__group__alloc.html#ga5485779c8f1948238fc4e92232fa65e1">vmaDestroyPool</a></div><div class="ttdeci">void vmaDestroyPool(VmaAllocator allocator, VmaPool pool)</div><div class="ttdoc">Destroys VmaPool object and frees Vulkan device memory.</div></div>
<div class="ttc" id="agroup__group__alloc_html_ga5c8770ded7c59c8caac6de0c2cb00b50"><div class="ttname"><a href="group__group__alloc.html#ga5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a></div><div class="ttdeci">VkResult vmaCreatePool(VmaAllocator allocator, const VmaPoolCreateInfo *pCreateInfo, VmaPool *pPool)</div><div class="ttdoc">Allocates Vulkan device memory and creates VmaPool object.</div></div>
<div class="ttc" id="agroup__group__alloc_html_gae790ab9ffaf7667fb8f62523e6897888"><div class="ttname"><a href="group__group__alloc.html#gae790ab9ffaf7667fb8f62523e6897888">vmaFindMemoryTypeIndexForBufferInfo</a></div><div class="ttdeci">VkResult vmaFindMemoryTypeIndexForBufferInfo(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, uint32_t *pMemoryTypeIndex)</div><div class="ttdoc">Helps to find memoryTypeIndex, given VkBufferCreateInfo and VmaAllocationCreateInfo.</div></div>
<div class="ttc" id="agroup__group__alloc_html_ggaa5846affa1e9da3800e3e78fae2305cca27cde9026a84d34d525777baa41fce6e"><div class="ttname"><a href="group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca27cde9026a84d34d525777baa41fce6e">VMA_MEMORY_USAGE_AUTO</a></div><div class="ttdeci">@ VMA_MEMORY_USAGE_AUTO</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:551</div></div>
<div class="ttc" id="astruct_vma_allocation_create_info_html"><div class="ttname"><a href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a></div><div class="ttdoc">Parameters of new VmaAllocation.</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:1292</div></div>
<div class="ttc" id="astruct_vma_allocation_create_info_html_accb8b06b1f677d858cb9af20705fa910"><div class="ttname"><a href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">VmaAllocationCreateInfo::usage</a></div><div class="ttdeci">VmaMemoryUsage usage</div><div class="ttdoc">Intended usage of memory.</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:1300</div></div>
<div class="ttc" id="astruct_vma_pool_create_info_html"><div class="ttname"><a href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a></div><div class="ttdoc">Describes parameter of created VmaPool.</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:1343</div></div>
<div class="ttc" id="astruct_vma_pool_create_info_html_a596fa76b685d3f1f688f84a709a5b319"><div class="ttname"><a href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">VmaPoolCreateInfo::memoryTypeIndex</a></div><div class="ttdeci">uint32_t memoryTypeIndex</div><div class="ttdoc">Vulkan memory type index to allocate this pool from.</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:1346</div></div>
<div class="ttc" id="astruct_vma_pool_create_info_html_ab6f2e52c47bfe1f4b44920b8bfc27b41"><div class="ttname"><a href="struct_vma_pool_create_info.html#ab6f2e52c47bfe1f4b44920b8bfc27b41">VmaPoolCreateInfo::pMemoryAllocateNext</a></div><div class="ttdeci">void *VkMemoryAllocateInfo pMemoryAllocateNext</div><div class="ttdoc">Additional pNext chain to be attached to VkMemoryAllocateInfo used for every allocation made by this ...</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:1395</div></div>
<div class="ttc" id="astruct_vma_pool_html"><div class="ttname"><a href="struct_vma_pool.html">VmaPool</a></div><div class="ttdoc">Represents custom memory pool.</div></div>
</div><!-- fragment --><p>Note that the structure passed as <a class="el" href="struct_vma_pool_create_info.html#ab6f2e52c47bfe1f4b44920b8bfc27b41" title="Additional pNext chain to be attached to VkMemoryAllocateInfo used for every allocation made by this ...">VmaPoolCreateInfo::pMemoryAllocateNext</a> must remain alive and unchanged for the whole lifetime of the custom pool, because it will be used when the pool allocates a new device memory block. No copy is made internally. This is why variable <span class="tt">exportMemAllocInfo</span> is defined as static.</p>
<p>If you want to export all memory allocated by VMA from certain memory types, also dedicated allocations or other allocations made from default pools, an alternative solution is to fill in <a class="el" href="struct_vma_allocator_create_info.html#ae8f0db05e5cb4c43d7713bf4a49a736b" title="Either null or a pointer to an array of external memory handle types for each Vulkan memory type.">VmaAllocatorCreateInfo::pTypeExternalMemoryHandleTypes</a>. It should point to an array with <span class="tt">VkExternalMemoryHandleTypeFlagsKHR</span> to be automatically passed by the library through <span class="tt">VkExportMemoryAllocateInfoKHR</span> on each allocation made from a specific memory type. You should not mix these two methods in a way that allows to apply both to the same memory type. Otherwise, <span class="tt">VkExportMemoryAllocateInfoKHR</span> structure would be attached twice to the <span class="tt">pNext</span> chain of <span class="tt">VkMemoryAllocateInfo</span>.</p>
<h2 class="doxsection"><a class="anchor" id="other_api_interop_exporting_memory_allocation"></a>
Memory allocation</h2>
<p>Finally, you can create a buffer with an allocation out of the custom pool. The buffer should use same flags as the sample buffer used to find the memory type. It should also specify <span class="tt">VkExternalMemoryBufferCreateInfoKHR</span> in its <span class="tt">pNext</span> chain.</p>
<div class="fragment"><div class="line">VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {</div>
<div class="line"> VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,</div>
<div class="line"> <span class="keyword">nullptr</span>,</div>
<div class="line"> handleType</div>
<div class="line">};</div>
<div class="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div>
<div class="line">bufCreateInfo.size = <span class="comment">// Your desired buffer size.</span></div>
<div class="line">bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div>
<div class="line">bufCreateInfo.pNext = &amp;externalMemBufCreateInfo;</div>
<div class="line"> </div>
<div class="line"><a class="code hl_struct" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div>
<div class="line">allocCreateInfo.<a class="code hl_variable" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> = pool; <span class="comment">// It is enough to set this one member.</span></div>
<div class="line"> </div>
<div class="line">VkBuffer buf;</div>
<div class="line"><a class="code hl_struct" href="struct_vma_allocation.html">VmaAllocation</a> alloc;</div>
<div class="line">res = <a class="code hl_function" href="group__group__alloc.html#gac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(g_Allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, <span class="keyword">nullptr</span>);</div>
<div class="line"><span class="comment">// Check res...</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// YOUR OTHER CODE COMES HERE....</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// At the end, don&#39;t forget to destroy it!</span></div>
<div class="line"><a class="code hl_function" href="group__group__alloc.html#ga0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a>(g_Allocator, buf, alloc);</div>
<div class="ttc" id="agroup__group__alloc_html_ga0d9f4e4ba5bf9aab1f1c746387753d77"><div class="ttname"><a href="group__group__alloc.html#ga0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a></div><div class="ttdeci">void vmaDestroyBuffer(VmaAllocator allocator, VkBuffer buffer, VmaAllocation allocation)</div><div class="ttdoc">Destroys Vulkan buffer and frees allocated memory.</div></div>
<div class="ttc" id="agroup__group__alloc_html_gac72ee55598617e8eecca384e746bab51"><div class="ttname"><a href="group__group__alloc.html#gac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a></div><div class="ttdeci">VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)</div><div class="ttdoc">Creates a new VkBuffer, allocates and binds memory for it.</div></div>
<div class="ttc" id="astruct_vma_allocation_create_info_html_a6272c0555cfd1fe28bff1afeb6190150"><div class="ttname"><a href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">VmaAllocationCreateInfo::pool</a></div><div class="ttdeci">VmaPool pool</div><div class="ttdoc">Pool that this allocation should be created in.</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:1324</div></div>
<div class="ttc" id="astruct_vma_allocation_html"><div class="ttname"><a href="struct_vma_allocation.html">VmaAllocation</a></div><div class="ttdoc">Represents single memory allocation.</div></div>
</div><!-- fragment --><p>If you need each allocation to have its own device memory block and start at offset 0, you can still do by using <a class="el" href="group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f" title="Set this flag if the allocation should have its own memory block.">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> flag. It works also with custom pools.</p>
<h2 class="doxsection"><a class="anchor" id="other_api_interop_exporting_exporting_win32_handle"></a>
Exporting Win32 handle</h2>
<p>After the allocation is created, you can acquire a Win32 <span class="tt">HANDLE</span> to the <span class="tt">VkDeviceMemory</span> block it belongs to. VMA function <a class="el" href="group__group__alloc.html#ga1a8d7aba3bf5a4de66c801b9988afa58" title="Given an allocation, returns Win32 handle that may be imported by other processes or APIs.">vmaGetMemoryWin32Handle2()</a> is a replacement of the Vulkan function <span class="tt">vkGetMemoryWin32HandleKHR</span>.</p>
<div class="fragment"><div class="line">HANDLE handle;</div>
<div class="line">res = <a class="code hl_function" href="group__group__alloc.html#ga1a8d7aba3bf5a4de66c801b9988afa58">vmaGetMemoryWin32Handle2</a>(g_Allocator, alloc, handleType, <span class="keyword">nullptr</span>, &amp;handle);</div>
<div class="line"><span class="comment">// Check res...</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// YOUR OTHER CODE COMES HERE....</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// At the end, you must close the handle.</span></div>
<div class="line">CloseHandle(handle);</div>
<div class="ttc" id="agroup__group__alloc_html_ga1a8d7aba3bf5a4de66c801b9988afa58"><div class="ttname"><a href="group__group__alloc.html#ga1a8d7aba3bf5a4de66c801b9988afa58">vmaGetMemoryWin32Handle2</a></div><div class="ttdeci">VkResult vmaGetMemoryWin32Handle2(VmaAllocator allocator, VmaAllocation allocation, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE hTargetProcess, HANDLE *pHandle)</div><div class="ttdoc">Given an allocation, returns Win32 handle that may be imported by other processes or APIs.</div></div>
</div><!-- fragment --><p>Documentation of the VK_KHR_external_memory_win32 extension states that:</p>
<blockquote class="doxtable">
<p>If handleType is defined as an NT handle, vkGetMemoryWin32HandleKHR must be called no more than once for each valid unique combination of memory and handleType. </p>
</blockquote>
<p>This is ensured automatically inside VMA. If <span class="tt">VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT</span> is used as the handle type, or other NT handle types, the library fetches the handle on first use, remembers it internally, and closes it when the memory block or dedicated allocation is destroyed. Every time you call <a class="el" href="group__group__alloc.html#ga1a8d7aba3bf5a4de66c801b9988afa58" title="Given an allocation, returns Win32 handle that may be imported by other processes or APIs.">vmaGetMemoryWin32Handle2()</a>, VMA calls <span class="tt">DuplicateHandle</span> and returns a new handle that you need to close. For further information, please check the documentation of this function.</p>
<h2 class="doxsection"><a class="anchor" id="other_api_interop_exporting_custom_alignment"></a>
Custom alignment</h2>
<p>Buffers or images exported to a different API like OpenGL may require a different alignment, higher than the one used by the library automatically, queried from functions like <span class="tt">vkGetBufferMemoryRequirements</span>. To impose such alignment:</p>
<p>You can create <a class="el" href="custom_memory_pools.html">Custom memory pools</a> for such allocations. Set <a class="el" href="struct_vma_pool_create_info.html#ade3eca546f0c6ab4e8fbf20eb6d854cb" title="Additional minimum alignment to be used for all allocations created from this pool....">VmaPoolCreateInfo::minAllocationAlignment</a> member to the minimum alignment required for each allocation to be made out of this pool. The alignment actually used will be the maximum of this member and the alignment returned for the specific buffer or image from a function like <span class="tt">vkGetBufferMemoryRequirements</span>, which is called by VMA automatically.</p>
<p>If you want to create a buffer with a specific minimum alignment out of default pools, you can use special function <a class="el" href="group__group__alloc.html#gaa06a690013a0d01e60894ac378083834" title="Creates a buffer with additional minimum alignment.">vmaCreateBufferWithAlignment()</a>, which takes additional parameter <span class="tt">minAlignment</span>.</p>
<p>Note the problem of alignment affects only resources placed inside bigger <span class="tt">VkDeviceMemory</span> blocks and not dedicated allocations, as these, by definition, always have alignment = 0 because the resource is bound to the beginning of its dedicated block. You can ensure that an allocation is created as dedicated by using <a class="el" href="group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f" title="Set this flag if the allocation should have its own memory block.">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a>. Contrary to Direct3D 12, Vulkan doesn't have a concept of alignment of the entire memory block passed on its allocation.</p>
<h2 class="doxsection"><a class="anchor" id="other_api_interop_exporting_extended_allocation_information"></a>
Extended allocation information</h2>
<p>If you want to rely on VMA to allocate your buffers and images inside larger memory blocks, but you need to know the size of the entire block and whether the allocation was made with its own dedicated memory, use function <a class="el" href="group__group__alloc.html#ga1405cf3eae2fd1305d645879173031a0" title="Returns extended information about specified allocation.">vmaGetAllocationInfo2()</a> to retrieve extended allocation information in structure <a class="el" href="struct_vma_allocation_info2.html" title="Extended parameters of a VmaAllocation object that can be retrieved using function vmaGetAllocationIn...">VmaAllocationInfo2</a>, which provides extra members: <span class="tt">blockSize</span> and <span class="tt">dedicatedMemory</span>.</p>
<h1 class="doxsection"><a class="anchor" id="other_api_interop_importing_memory"></a>
Importing memory</h1>
<p>Importing external memory requires attaching an extra structure like <span class="tt">VkImportMemoryWin32HandleInfoKHR</span> to the <span class="tt">pNext</span> chain of <span class="tt">VkMemoryAllocateInfo</span> structure. VMA offers support for it by providing functions that allocate memory, create a buffer or an image always with a dedicated <span class="tt">VkDeviceMemory</span> block and accept custom <span class="tt">pNext</span> pointer: <a class="el" href="group__group__alloc.html#ga9a0b91c157adec03dae1e6ea78d33625" title="General purpose allocation of a dedicated memory.">vmaAllocateDedicatedMemory()</a>, <a class="el" href="group__group__alloc.html#gab313b89299877ca21c196027bed9e874" title="Creates a dedicated buffer while offering extra parameter pMemoryAllocateNext.">vmaCreateDedicatedBuffer()</a>, <a class="el" href="group__group__alloc.html#ga07c66ffa000906a599d471047a7c0324" title="Function similar to vmaCreateDedicatedBuffer() but for images.">vmaCreateDedicatedImage()</a>. Example:</p>
<div class="fragment"><div class="line"><span class="keyword">constexpr</span> VkExternalMemoryHandleTypeFlagBits handleType =</div>
<div class="line"> VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;</div>
<div class="line"> </div>
<div class="line">VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {</div>
<div class="line"> VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR };</div>
<div class="line">externalMemBufCreateInfo.handleTypes = handleType;</div>
<div class="line"> </div>
<div class="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div>
<div class="line">bufCreateInfo.pNext = &amp;externalMemBufCreateInfo; <span class="comment">// !!!</span></div>
<div class="line">bufCreateInfo.size = ...</div>
<div class="line">bufCreateInfo.usage = ...</div>
<div class="line"> </div>
<div class="line">VkImportMemoryWin32HandleInfoKHR importInfo = {</div>
<div class="line"> VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR };</div>
<div class="line">importInfo.handleType = handleType;</div>
<div class="line">importInfo.handle = myExternalHandleToImport;</div>
<div class="line"> </div>
<div class="line"><a class="code hl_struct" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div>
<div class="line">allocCreateInfo.<a class="code hl_variable" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code hl_enumvalue" href="group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca27cde9026a84d34d525777baa41fce6e">VMA_MEMORY_USAGE_AUTO</a>;</div>
<div class="line"> </div>
<div class="line">VkBuffer buf = VK_NULL_HANDLE;</div>
<div class="line"><a class="code hl_struct" href="struct_vma_allocation.html">VmaAllocation</a> alloc = VK_NULL_HANDLE;</div>
<div class="line">VkResult res = <a class="code hl_function" href="group__group__alloc.html#gab313b89299877ca21c196027bed9e874">vmaCreateDedicatedBuffer</a>(allocator, &amp;bufCreateInfo, &amp;allocCreateInfo,</div>
<div class="line"> &amp;importInfo, <span class="comment">// pMemoryAllocateNext !!!</span></div>
<div class="line"> &amp;buf, &amp;alloc, <span class="keyword">nullptr</span>);</div>
<div class="line"><span class="comment">// Check res...</span></div>
<div class="ttc" id="agroup__group__alloc_html_gab313b89299877ca21c196027bed9e874"><div class="ttname"><a href="group__group__alloc.html#gab313b89299877ca21c196027bed9e874">vmaCreateDedicatedBuffer</a></div><div class="ttdeci">VkResult vmaCreateDedicatedBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, void *(VkMemoryAllocateInfo) pMemoryAllocateNext, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)</div><div class="ttdoc">Creates a dedicated buffer while offering extra parameter pMemoryAllocateNext.</div></div>
</div><!-- fragment --> </div></div><!-- contents -->
</div><!-- PageDoc -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.14.0
</small></address>
</div><!-- doc-content -->
</body>
</html>