blob: ef384884900f5489236fff154fd16c477e7ab8c0 [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.9.5"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Direct3D 12 Memory Allocator: Resource aliasing (overlap)</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>
<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">Direct3D 12 Memory Allocator
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.5 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</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 class="el" href="index.html">D3D12 Memory Allocator</a></li> </ul>
</div>
</div><!-- top -->
<div><div class="header">
<div class="headertitle"><div class="title">Resource aliasing (overlap) </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p >New explicit graphics APIs (Vulkan and Direct3D 12), thanks to manual memory management, give an opportunity to alias (overlap) multiple resources in the same region of memory - a feature not available in the old APIs (Direct3D 11, OpenGL). It can be useful to save video memory, but it must be used with caution.</p>
<p >For example, if you know the flow of your whole render frame in advance, you are going to use some intermediate textures or buffers only during a small range of render passes, and you know these ranges don't overlap in time, you can create these resources in the same place in memory, even if they have completely different parameters (width, height, format etc.).</p>
<p ><img src="../gfx/Aliasing.png" alt="Resource aliasing (overlap)" class="inline"/></p>
<p >Such scenario is possible using <a class="el" href="namespace_d3_d12_m_a.html">D3D12MA</a>, but you need to create your resources using special function <a class="el" href="class_d3_d12_m_a_1_1_allocator.html#ab45536f92410aedb7be44ea36b1b4717" title="Creates a new resource in place of an existing allocation. This is useful for memory aliasing.">D3D12MA::Allocator::CreateAliasingResource</a>. Before that, you need to allocate memory with parameters calculated using formula:</p>
<ul>
<li>allocation size = max(size of each resource)</li>
<li>allocation alignment = max(alignment of each resource)</li>
</ul>
<p >Following example shows two different textures created in the same place in memory, allocated to fit largest of them.</p>
<div class="fragment"><div class="line">D3D12_RESOURCE_DESC resDesc1 = {};</div>
<div class="line">resDesc1.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;</div>
<div class="line">resDesc1.Alignment = 0;</div>
<div class="line">resDesc1.Width = 1920;</div>
<div class="line">resDesc1.Height = 1080;</div>
<div class="line">resDesc1.DepthOrArraySize = 1;</div>
<div class="line">resDesc1.MipLevels = 1;</div>
<div class="line">resDesc1.Format = DXGI_FORMAT_R8G8B8A8_UNORM;</div>
<div class="line">resDesc1.SampleDesc.Count = 1;</div>
<div class="line">resDesc1.SampleDesc.Quality = 0;</div>
<div class="line">resDesc1.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;</div>
<div class="line">resDesc1.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;</div>
<div class="line"> </div>
<div class="line">D3D12_RESOURCE_DESC resDesc2 = {};</div>
<div class="line">resDesc2.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;</div>
<div class="line">resDesc2.Alignment = 0;</div>
<div class="line">resDesc2.Width = 1024;</div>
<div class="line">resDesc2.Height = 1024;</div>
<div class="line">resDesc2.DepthOrArraySize = 1;</div>
<div class="line">resDesc2.MipLevels = 0;</div>
<div class="line">resDesc2.Format = DXGI_FORMAT_R8G8B8A8_UNORM;</div>
<div class="line">resDesc2.SampleDesc.Count = 1;</div>
<div class="line">resDesc2.SampleDesc.Quality = 0;</div>
<div class="line">resDesc2.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;</div>
<div class="line">resDesc2.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;</div>
<div class="line"> </div>
<div class="line"><span class="keyword">const</span> D3D12_RESOURCE_ALLOCATION_INFO allocInfo1 =</div>
<div class="line"> device-&gt;GetResourceAllocationInfo(0, 1, &amp;resDesc1);</div>
<div class="line"><span class="keyword">const</span> D3D12_RESOURCE_ALLOCATION_INFO allocInfo2 =</div>
<div class="line"> device-&gt;GetResourceAllocationInfo(0, 1, &amp;resDesc2);</div>
<div class="line"> </div>
<div class="line">D3D12_RESOURCE_ALLOCATION_INFO finalAllocInfo = {};</div>
<div class="line">finalAllocInfo.Alignment = std::max(allocInfo1.Alignment, allocInfo2.Alignment);</div>
<div class="line">finalAllocInfo.SizeInBytes = std::max(allocInfo1.SizeInBytes, allocInfo2.SizeInBytes);</div>
<div class="line"> </div>
<div class="line"><a class="code hl_struct" href="struct_d3_d12_m_a_1_1_a_l_l_o_c_a_t_i_o_n___d_e_s_c.html">D3D12MA::ALLOCATION_DESC</a> allocDesc = {};</div>
<div class="line">allocDesc.<a class="code hl_variable" href="struct_d3_d12_m_a_1_1_a_l_l_o_c_a_t_i_o_n___d_e_s_c.html#aa46b3c0456e5a23edef3328607ebf4d7">HeapType</a> = D3D12_HEAP_TYPE_DEFAULT;</div>
<div class="line">allocDesc.<a class="code hl_variable" href="struct_d3_d12_m_a_1_1_a_l_l_o_c_a_t_i_o_n___d_e_s_c.html#a97878838f976b2d1e6b1a76881035690">ExtraHeapFlags</a> = D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES;</div>
<div class="line"> </div>
<div class="line"><a class="code hl_class" href="class_d3_d12_m_a_1_1_allocation.html">D3D12MA::Allocation</a>* alloc;</div>
<div class="line">hr = allocator-&gt;AllocateMemory(&amp;allocDesc, &amp;finalAllocInfo, &amp;alloc);</div>
<div class="line">assert(alloc != NULL &amp;&amp; alloc-&gt;<a class="code hl_function" href="class_d3_d12_m_a_1_1_allocation.html#adca8d5a82bed492fe7265fcda6e53da2">GetHeap</a>() != NULL);</div>
<div class="line"> </div>
<div class="line">ID3D12Resource* res1;</div>
<div class="line">hr = allocator-&gt;CreateAliasingResource(</div>
<div class="line"> alloc,</div>
<div class="line"> 0, <span class="comment">// AllocationLocalOffset</span></div>
<div class="line"> &amp;resDesc1,</div>
<div class="line"> D3D12_RESOURCE_STATE_COMMON,</div>
<div class="line"> NULL, <span class="comment">// pOptimizedClearValue</span></div>
<div class="line"> IID_PPV_ARGS(&amp;res1));</div>
<div class="line"> </div>
<div class="line">ID3D12Resource* res2;</div>
<div class="line">hr = allocator-&gt;CreateAliasingResource(</div>
<div class="line"> alloc,</div>
<div class="line"> 0, <span class="comment">// AllocationLocalOffset</span></div>
<div class="line"> &amp;resDesc2,</div>
<div class="line"> D3D12_RESOURCE_STATE_COMMON,</div>
<div class="line"> NULL, <span class="comment">// pOptimizedClearValue</span></div>
<div class="line"> IID_PPV_ARGS(&amp;res2));</div>
<div class="line"> </div>
<div class="line"><span class="comment">// You can use res1 and res2, but not at the same time!</span></div>
<div class="line"> </div>
<div class="line">res2-&gt;Release();</div>
<div class="line">res1-&gt;Release();</div>
<div class="line">alloc-&gt;Release();</div>
<div class="ttc" id="aclass_d3_d12_m_a_1_1_allocation_html"><div class="ttname"><a href="class_d3_d12_m_a_1_1_allocation.html">D3D12MA::Allocation</a></div><div class="ttdoc">Represents single memory allocation.</div><div class="ttdef"><b>Definition:</b> D3D12MemAlloc.h:461</div></div>
<div class="ttc" id="aclass_d3_d12_m_a_1_1_allocation_html_adca8d5a82bed492fe7265fcda6e53da2"><div class="ttname"><a href="class_d3_d12_m_a_1_1_allocation.html#adca8d5a82bed492fe7265fcda6e53da2">D3D12MA::Allocation::GetHeap</a></div><div class="ttdeci">ID3D12Heap * GetHeap() const</div><div class="ttdoc">Returns memory heap that the resource is created in.</div></div>
<div class="ttc" id="astruct_d3_d12_m_a_1_1_a_l_l_o_c_a_t_i_o_n___d_e_s_c_html"><div class="ttname"><a href="struct_d3_d12_m_a_1_1_a_l_l_o_c_a_t_i_o_n___d_e_s_c.html">D3D12MA::ALLOCATION_DESC</a></div><div class="ttdoc">Parameters of created D3D12MA::Allocation object. To be used with Allocator::CreateResource.</div><div class="ttdef"><b>Definition:</b> D3D12MemAlloc.h:278</div></div>
<div class="ttc" id="astruct_d3_d12_m_a_1_1_a_l_l_o_c_a_t_i_o_n___d_e_s_c_html_a97878838f976b2d1e6b1a76881035690"><div class="ttname"><a href="struct_d3_d12_m_a_1_1_a_l_l_o_c_a_t_i_o_n___d_e_s_c.html#a97878838f976b2d1e6b1a76881035690">D3D12MA::ALLOCATION_DESC::ExtraHeapFlags</a></div><div class="ttdeci">D3D12_HEAP_FLAGS ExtraHeapFlags</div><div class="ttdoc">Additional heap flags to be used when allocating memory.</div><div class="ttdef"><b>Definition:</b> D3D12MemAlloc.h:303</div></div>
<div class="ttc" id="astruct_d3_d12_m_a_1_1_a_l_l_o_c_a_t_i_o_n___d_e_s_c_html_aa46b3c0456e5a23edef3328607ebf4d7"><div class="ttname"><a href="struct_d3_d12_m_a_1_1_a_l_l_o_c_a_t_i_o_n___d_e_s_c.html#aa46b3c0456e5a23edef3328607ebf4d7">D3D12MA::ALLOCATION_DESC::HeapType</a></div><div class="ttdeci">D3D12_HEAP_TYPE HeapType</div><div class="ttdoc">The type of memory heap where the new allocation should be placed.</div><div class="ttdef"><b>Definition:</b> D3D12MemAlloc.h:287</div></div>
</div><!-- fragment --><p >Remember that using resouces that alias in memory requires proper synchronization. You need to issue a special barrier of type <code>D3D12_RESOURCE_BARRIER_TYPE_ALIASING</code>. You also need to treat a resource after aliasing as uninitialized - containing garbage data. For example, if you use <code>res1</code> and then want to use <code>res2</code>, you need to first initialize <code>res2</code> using either Clear, Discard, or Copy to the entire resource.</p>
<p >Additional considerations:</p>
<ul>
<li>D3D12 also allows to interpret contents of memory between aliasing resources consistently in some cases, which is called "data inheritance". For details, see Microsoft documentation chapter "Memory Aliasing and Data Inheritance".</li>
<li>You can create more complex layout where different textures and buffers are bound at different offsets inside one large allocation. For example, one can imagine a big texture used in some render passes, aliasing with a set of many small buffers used in some further passes. To bind a resource at non-zero offset of an allocation, call <a class="el" href="class_d3_d12_m_a_1_1_allocator.html#ab45536f92410aedb7be44ea36b1b4717" title="Creates a new resource in place of an existing allocation. This is useful for memory aliasing.">D3D12MA::Allocator::CreateAliasingResource</a> with appropriate value of <code>AllocationLocalOffset</code> parameter.</li>
<li>Resources of the three categories: buffers, textures with <code>RENDER_TARGET</code> or <code>DEPTH_STENCIL</code> flags, and all other textures, can be placed in the same memory only when <code>allocator-&gt;GetD3D12Options().ResourceHeapTier &gt;= D3D12_RESOURCE_HEAP_TIER_2</code>. Otherwise they must be placed in different memory heap types, and thus aliasing them is not possible. </li>
</ul>
</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.9.5
</small></address>
</body>
</html>