{"id":2618,"date":"2019-11-11T10:24:38","date_gmt":"2019-11-11T18:24:38","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/directx\/?p=2618"},"modified":"2019-11-11T12:25:54","modified_gmt":"2019-11-11T20:25:54","slug":"coming-to-directx-12-more-control-over-memory-allocation","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/directx\/coming-to-directx-12-more-control-over-memory-allocation\/","title":{"rendered":"Coming to DirectX 12: More control over memory allocation"},"content":{"rendered":"<p>In the next update to Windows, D3D12 will be adding two new flags to the <strong>D3D12_HEAP_FLAG<\/strong> enumeration. These new flags are \u201cimpermanent\u201d properties, which don\u2019t affect the resulting memory itself, but rather the <u>way<\/u> in which it\u2019s allocated. As such, it\u2019s important to call out that these flags aren\u2019t reflected from ID3D12Heap::GetDesc or ID3D12Resource::GetHeapProperties. Let\u2019s dive in.<\/p>\n<p><strong>D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT<\/strong><\/p>\n<p>Today, when you ask D3D to allocate a heap or committed resource, the last thing that happens before you get back your object is the memory gets made resident. This is equivalent to a call to ID3D12Device::MakeResident being performed. There\u2019s two problems with this:<\/p>\n<ol>\n<li>MakeResident\u2019s design is that it blocks your CPU thread until the memory is fully ready to use. Sometimes this isn\u2019t what you want.<\/li>\n<li>MakeResident will allow you to overcommit memory, beyond what the current process budget indicates you should be using.<\/li>\n<\/ol>\n<p>Oddly enough, these two reasons are <u>exactly<\/u> the reasons that we added ID3D12Device3::EnqueueMakeResident. This allows apps to make different choices here, such as waiting for residency using the GPU rather than the CPU, or requesting the residency op to fail rather than going over-budget. By allocating memory in a non-resident state, now app developers can apply both of these benefits to their first use of resources as well.<\/p>\n<p><strong>D3D12_HEAP_FLAG_CREATE_NOT_ZEROED<\/strong><\/p>\n<p>This is one of those things that D3D has never clearly called out before, but I\u2019m going to go ahead and make this statement: Committed resources and heaps newly created by D3D will almost always* have zeroed contents in them. This used to be an implementation detail, but during the development of the WDDM2.0 memory manager, we attempted to improve things here, by enabling more re-use memory that had never left the confines of a given process without zeroing. As it turns out, this had catastrophic consequences, because applications in the Windows ecosystem have taken hard dependencies on the fact that new resources with given properties are zeroed \u2013 maybe without even realizing that they had done so.<\/p>\n<p><span style=\"font-size: 8pt;\">* Actual zeroing depending on resource size and CPU visibility, with details of what properties changing from one OS release to another, and from one CPU architecture to another.<\/span><\/p>\n<p>So, we had to go back to returning zeroed memory. Why is this bad? Because it\u2019s expensive! It means that the memory manager needs to explicitly write zeroes into the memory before it returns it to you \u2013 this might happen during the create call, or it might be deferred until you first access the memory, but it\u2019s going to happen.<\/p>\n<p>Now we\u2019re giving developers the ability to opt out of this cost by simply specifying this new flag during heap\/resource allocation. However, it\u2019s important to note that <u>this is not a guarantee<\/u>, this is only an optimization. You will still get back zeroed memory if the only memory available is coming to you from another process, for security and process isolation purposes, but when you have memory that you\u2019ve freed that can be re-used, that memory can be cheaply recycled without having to re-zero it.<\/p>\n<p>It&#8217;s important to note that the rules for accessing uninitialized memory apply here, the same way that they would for creating placed resources or mapping tiles into reserved resources \u2013 resources with the render target or depth stencil flags must be cleared, discarded, or copied to before they can be used. See the \u201c<a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/api\/d3d12\/nf-d3d12-id3d12device-createplacedresource#notes-on-the-required-resource-initialization\">Notes on the required resource initialization<\/a>\u201d section of the documentation for CreatePlacedResource.<\/p>\n<p>These flags sound great, right? What\u2019s the catch? The only catch is you have to make sure they\u2019re available before you can leverage them. These flags don\u2019t require new drivers, all they require is that you\u2019re running on a version of D3D12 which understands them. There\u2019s no dedicated CheckFeatureSupport option for these, they\u2019re available anytime that ID3D12Device8 is exposed, or a check for D3D12_FEATURE_D3D12_OPTIONS7 succeeds.<\/p>\n<p><strong>Getting Started<\/strong>\nTo use these flags in your application, install the latest Windows 10 Insider Preview build and SDK Preview Build for Windows 10 (20H1) from the Windows Insider Program.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the next update to Windows, D3D12 will be adding two new flags to the D3D12_HEAP_FLAG enumeration. These new flags are \u201cimpermanent\u201d properties, which don\u2019t affect the resulting memory itself, but rather the way in which it\u2019s allocated. This gives app developers more control and flexibility.<\/p>\n","protected":false},"author":2474,"featured_media":12651,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2618","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-directx"],"acf":[],"blog_post_summary":"<p>In the next update to Windows, D3D12 will be adding two new flags to the D3D12_HEAP_FLAG enumeration. These new flags are \u201cimpermanent\u201d properties, which don\u2019t affect the resulting memory itself, but rather the way in which it\u2019s allocated. This gives app developers more control and flexibility.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/directx\/wp-json\/wp\/v2\/posts\/2618","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/directx\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/directx\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/directx\/wp-json\/wp\/v2\/users\/2474"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/directx\/wp-json\/wp\/v2\/comments?post=2618"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/directx\/wp-json\/wp\/v2\/posts\/2618\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/directx\/wp-json\/wp\/v2\/media\/12651"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/directx\/wp-json\/wp\/v2\/media?parent=2618"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/directx\/wp-json\/wp\/v2\/categories?post=2618"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/directx\/wp-json\/wp\/v2\/tags?post=2618"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}