{"id":5023,"date":"2020-09-08T08:00:26","date_gmt":"2020-09-08T15:00:26","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/pix\/?p=5023"},"modified":"2024-01-02T15:12:17","modified_gmt":"2024-01-02T23:12:17","slug":"debugging-d3d11-apps-using-d3d11on12","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/pix\/debugging-d3d11-apps-using-d3d11on12\/","title":{"rendered":"Debugging D3D11 apps using D3D11On12"},"content":{"rendered":"<p>PIX is designed for use with Direct3D12 applications. That said, PIX can take advantage of Windows\u2019 ability to convert Direct3D11 API calls into Direct3D12 calls, and thereby allow you to view your Direct3D11 application as if it were Direct3D12. It\u2019s easy to use: just click this check box here before launching your game under GPU capture:<\/p>\n<p><img decoding=\"async\" width=\"603\" height=\"338\" class=\"wp-image-5025 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image.png\" srcset=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image.png 603w, https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-300x168.png 300w\" sizes=\"(max-width: 603px) 100vw, 603px\" \/><\/p>\n<p>PIX will also work if you\u2019ve used the <a href=\"https:\/\/devblogs.microsoft.com\/directx\/d3dconfig-a-new-tool-to-manage-directx-control-panel-settings\/\">d3dconfig<\/a> (available as of Windows May 2020 Update) tool to turn on D3D11On12 yourself via a command like<\/p>\n<p style=\"padding-left: 40px;\"><span style=\"font-family: 'courier new', courier, monospace;\">d3dconfig apps \u2011\u2011add MyGame.exe<\/span><\/p>\n<p style=\"padding-left: 40px;\"><span style=\"font-family: 'courier new', courier, monospace;\">d3dconfig device force-d3d11on12=true<\/span><\/p>\n<p>Either of these mechanisms turns on the D3D11On12 layer to translate D3D11 calls to D3D12 calls. To help you visualize what\u2019s going on, and the implications thereof that we\u2019ll detail below, here\u2019s a simplified view of the various software components in play when you capture your application in PIX using D3D11On12:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-medium wp-image-5036 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/11on12Architecture-220x300.jpg\" alt=\"Image 11on12Architecture\" width=\"220\" height=\"300\" srcset=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/11on12Architecture-220x300.jpg 220w, https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/11on12Architecture.jpg 317w\" sizes=\"(max-width: 220px) 100vw, 220px\" \/><\/p>\n<p>Now, this system does work, but it should be pointed out that D3D11 is not PIX\u2019s focus, and hence some features currently work poorly or not at all. We make improvements to PIX all the time, though, and if there\u2019s sufficient interest (as expressed via the mechanisms listed on our <a href=\"https:\/\/devblogs.microsoft.com\/pix\/support-2\/\">support<\/a> page) we\u2019ll spend more effort on D3D11On12 and improve some of these experiences.<\/p>\n<h2>PIX Markers and Extra Events Generated by D3D11On12<\/h2>\n<p>The D3D11On12 layer will translate calls to <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/api\/d3d11_1\/nn-d3d11_1-id3duserdefinedannotation\">ID3DUserDefinedAnnotation<\/a> into PIX markers for you, so you don\u2019t need to change your D3D11 code at all. D3D11On12 will prepend \u201cD3D11 Event:\u201d in front of your own strings. Here\u2019s an example of such markers in PIX:<\/p>\n<p><img decoding=\"async\" width=\"690\" height=\"195\" class=\"wp-image-5027 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-2.png\" srcset=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-2.png 690w, https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-2-300x85.png 300w\" sizes=\"(max-width: 690px) 100vw, 690px\" \/><\/p>\n<p>In addition, D3D11On12 will generate its own PIX markers in order to denote the several D3D12 calls that emulate a single D3D11 call. Here are two examples of such markers, showing what happens for subsequent D3D11 calls to UpdateSubresource and DrawIndexed\/DrawIndexedInstanced:<\/p>\n<p><img decoding=\"async\" width=\"702\" height=\"224\" class=\"wp-image-5028 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-3.png\" srcset=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-3.png 702w, https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-3-300x96.png 300w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/p>\n<p>As you can see, D3D11On12 inserts many ResourceBarrier calls, which are of course unnecessary in D3D11 since their effects are implicit in D3D11\u2019s design.<\/p>\n<p>A SwapChain\u2019s Present call can turn into different calls depending on the Windows version, and what else is happening in the process. A simple example is:<\/p>\n<p><img decoding=\"async\" width=\"594\" height=\"135\" class=\"wp-image-5029 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-4.png\" srcset=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-4.png 594w, https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-4-300x68.png 300w\" sizes=\"(max-width: 594px) 100vw, 594px\" \/><\/p>\n<p>Here we see a ResourceBarrier being called for the swap chain backbuffer that is about to be presented, and a Signal on one of D3D11On12\u2019s own internal fences. Note that \u201cPresent\u201d was called by D3D11On12, but not IDXGISwapChain::Present. This Present is on ID3D12SharingContract, an interface used by DXGI to implement IDXGISwapChain::Present.<\/p>\n<h2>Limitation: No Shader Debug Data<\/h2>\n<p>D3D11On12 sits below D3D11 itself, and as you can see from the architectural layer diagram above, D3D11 treats D3D11On12 a bit like a display driver. Since display drivers don\u2019t need much of the metadata that travels with a shader blob, D3D11 discards that metadata. Specifically, the PDB data that a shader would have, were it compiled with the \/Zi flag, will not survive through to the D3D11On12 layer, and thus isn\u2019t available to PIX.<\/p>\n<p>This has several problematic effects on PIX. The most notable of these is that no shader source code is available, which means no source-level shader debugging. Shader reflection data is also lost, which means that PIX can\u2019t automatically show the format of a constant buffer, or know precisely which resources were accessed by a shader.<\/p>\n<h2>Limitation: Shader Debugging<\/h2>\n<p>As mentioned above, shader debugging can\u2019t show source code, but there is an additional limitation: D3D11On12 translates DXBC to DXIL. So, while you can debug at the DXIL level, you\u2019ll find it very difficult to make the mental mapping from what\u2019s going on in DXIL back to DXBC and from DXBC to HLSL.<\/p>\n<h2>Limitation: Inaccurate Warnings<\/h2>\n<p>PIX\u2019s Warnings pane can show false positives under D3D11On12. This is because D3D11On12 has to batch D3D11 calls into D3D12 command lists, and since it has no knowledge of the application\u2019s upcoming call sequence, can only make its best guess about when to flush these command lists. Consequently, you may see warnings such as \u201cSmall command lists executed\u201d or \u201cCommand list performing no GPU work\u201d that are no fault of your application.<\/p>\n<h2>Limitation: Timing Captures Show Almost No GPU Work<\/h2>\n<p>D3D11\u2019s infrastructure is not instrumented for GPU timing captures, so the only GPU events you can expect to record are VSYNCs. Since timing captures don\u2019t involve PIX\u2019s API-capture machinery, PIX cannot turn on D3D11On12 itself, so D3D11 markers will only be translated if you have turned on D3D11On12 via d3dconfig.exe, as noted above.<\/p>\n<h2>Things that Do Work!<\/h2>\n<p>Let\u2019s end this on a high note. You can expect the following major PIX features to work:<\/p>\n<ul>\n<li>Dr Pix<\/li>\n<li>Collecting timing data from a GPU capture:<\/li>\n<\/ul>\n<p><img decoding=\"async\" width=\"683\" height=\"153\" class=\"wp-image-5030 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-5.png\" srcset=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-5.png 683w, https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-5-300x67.png 300w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/p>\n<ul>\n<li>The Pipeline View:<\/li>\n<\/ul>\n<p><img decoding=\"async\" width=\"1099\" height=\"608\" class=\"wp-image-5031 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-6.png\" srcset=\"https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-6.png 1099w, https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-6-300x166.png 300w, https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-6-1024x567.png 1024w, https:\/\/devblogs.microsoft.com\/pix\/wp-content\/uploads\/sites\/41\/2020\/09\/word-image-6-768x425.png 768w\" sizes=\"(max-width: 1099px) 100vw, 1099px\" \/><\/p>\n<p>&#8230;as well as all the other usual D3D12 state inspection features of PIX.<\/p>\n<p>Let us know if you use PIX on D3D11 apps and have requests for features you\u2019d like to see work better. <a href=\"https:\/\/devblogs.microsoft.com\/pix\/support-2\/\">We\u2019re always listening<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>PIX is designed for use with Direct3D12 applications. That said, PIX can take advantage of Windows\u2019 ability to convert Direct3D11 API calls into Direct3D12 calls, and thereby allow you to view your Direct3D11 application as if it were Direct3D12. It\u2019s easy to use: just click this check box here before launching your game under GPU [&hellip;]<\/p>\n","protected":false},"author":1901,"featured_media":4769,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-5023","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pix"],"acf":[],"blog_post_summary":"<p>PIX is designed for use with Direct3D12 applications. That said, PIX can take advantage of Windows\u2019 ability to convert Direct3D11 API calls into Direct3D12 calls, and thereby allow you to view your Direct3D11 application as if it were Direct3D12. It\u2019s easy to use: just click this check box here before launching your game under GPU [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/posts\/5023","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/users\/1901"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/comments?post=5023"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/posts\/5023\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/media\/4769"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/media?parent=5023"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/categories?post=5023"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/tags?post=5023"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}