{"id":3055,"date":"2017-11-29T23:28:59","date_gmt":"2017-11-29T23:28:59","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/pix\/?page_id=3055"},"modified":"2023-10-16T09:56:11","modified_gmt":"2023-10-16T16:56:11","slug":"programmatic-capture","status":"publish","type":"page","link":"https:\/\/devblogs.microsoft.com\/pix\/programmatic-capture\/","title":{"rendered":"Programmatic Capture"},"content":{"rendered":"<p>PIX allows applications to take and configure GPU Captures programmatically using various APIs documented here. Starting with PIX on Windows version 2303.02, Timing Captures can also be taken programmatically.<\/p>\n<h3>Using pix3.h<\/h3>\n<p>pix3.h is included in the WinPixEventRuntime, which is documented <a href=\"https:\/\/devblogs.microsoft.com\/pix\/winpixeventruntime\/\">here<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h3>GPU Capture APIs in pix3.h<\/h3>\n<p>Before using the pix3 GPU Capture APIs, you must:<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li>Install PIX onto the target PC<\/li>\n<li>Add WinPixEventRuntime to your application (see docs <a href=\"https:\/\/devblogs.microsoft.com\/pix\/winpixeventruntime\/\">here<\/a>)<\/li>\n<li>Define one of these preprocessor symbols in your build: USE_PIX, DBG, _DEBUG, PROFILE, or PROFILE_BUILD.<\/li>\n<li>Include pix3.h in your application<\/li>\n<li>EITHER load a copy of WinPixGpuCapturer.dll into your application\u2019s process before calling any D3D12 APIs, such as D3D12CreateDevice\n<ul>\n<li>WinPixGpuCapturer is shipped with PIX, and not with WinPixEventRuntime.<\/li>\n<li>pix3.h contains a helper function, PIXLoadLatestWinPixGpuCapturerLibrary(), to find the library and load it for you. See docs below for details.<\/li>\n<li>You can also use the sample code <a style=\"background-color: #f7f7f9; font-size: 1rem;\" href=\"https:\/\/devblogs.microsoft.com\/pix\/taking-a-capture\/#attach\">here<\/a><span style=\"font-size: 1rem;\"> to manually find and load the library.<\/span><\/li>\n<\/ul>\n<\/li>\n<li>OR launch your application through PIX or pixtool\n<ul>\n<li><em>This will inject WinPixGpuCapturer.dll into your application for you.<\/em><\/li>\n<\/ul>\n<\/li>\n<li>Use APIs like PIXBeginCapture(), PIXSetTargetWindow(), etc in your application.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h3>Timing Capture APIs in pix3.h<\/h3>\n<p>Before using the pix3 GPU Capture APIs, you must:<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li>Install PIX onto the target PC<\/li>\n<li>Add WinPixEventRuntime to your application (see docs <a href=\"https:\/\/devblogs.microsoft.com\/pix\/winpixeventruntime\/\">here<\/a>)<\/li>\n<li>Define one of these preprocessor symbols in your build: USE_PIX, DBG, _DEBUG, PROFILE, or PROFILE_BUILD.<\/li>\n<li>Include pix3.h in your application<\/li>\n<li>Run your application as an Administrator (i.e. &#8220;elevated&#8221;)<\/li>\n<li>Load a copy of WinPixTimingCapturer.dll into your application\u2019s process\n<ul>\n<li>WinPixTimingCapturer is shipped with PIX, and not with WinPixEventRuntime.<\/li>\n<li>pix3.h contains a helper function, PIXLoadLatestWinPixTimingCapturerLibrary(), to find the library and load it for you. See docs below for details.<\/li>\n<\/ul>\n<\/li>\n<li>Use APIs like PIXBeginCapture(), etc in your application to take programmatic Timing Captures<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h3>Programmatic Capture API Documentation<\/h3>\n<p><strong>HMODULE PIXLoadLatestWinPixGpuCapturerLibrary()<\/strong><\/p>\n<p>This is a helper function that will find the latest PIX installation in Program Files on the current PC and LoadLibrary() its copy of WinPixGpuCapturer.dll for you. The function\u2019s semantics are similar to <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/api\/libloaderapi\/nf-libloaderapi-loadlibraryw\">LoadLibrary<\/a>(): upon success, it increments the module\u2019s reference count and returns a non-NULL module handle. This means that FreeLibrary() needs to be called on the module before it will be unloaded. Upon failure, the function returns nullptr and a detailed error can be accessed via GetLastError().<\/p>\n<p>&nbsp;<\/p>\n<p><strong>HMODULE PIXLoadLatestWinPixTimingCapturerLibrary()<\/strong><\/p>\n<p>This is similar to PIXLoadLatestWinPixGpuCapturerLibrary, except that it loads the latest copy of WinPixTimingCapturer.dll for you. This lets you take programmatic timing captures.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>HRESULT WINAPI PIXBeginCapture(DWORD captureFlags, _In_opt_ const PPIXCaptureParameters captureParameters)<\/strong><\/p>\n<p>This API immediately starts a programmatic capture and outputs it to the capture file specified in the captureParameters struct. Other parts of that struct are ignored. For compatibility with Xbox, captureFlags must be set to PIX_CAPTURE_GPU or PIX_CAPTURE_TIMING otherwise the function will return E_NOTIMPL.<\/p>\n<p>For GPU Captures:<\/p>\n<ul>\n<li>The capture filename specified in the captureParameters struct should use the .wpix file extension<\/li>\n<li>You may want to wait for all pending GPU work to finish executing before calling this API, to ensure that you capture everything that you expect to capture.<\/li>\n<\/ul>\n<p>For Timing Captures:<\/p>\n<pre class=\"prettyprint language-cpp\"><code class=\"language-cpp\">PCWSTR FileName;  \/\/ should be a path to a .wpix file\r\nUINT32 MaximumToolingMemorySizeMb; \/\/ ignored in PIX on Windows\r\nPIXCaptureStorage CaptureStorage; \/\/ ignored in PIX on Windows\r\n\r\nBOOL CaptureGpuTiming;\r\n\r\nBOOL CaptureCallstacks;\r\nBOOL CaptureCpuSamples;\r\nUINT32 CpuSamplesPerSecond; \/\/ If CaptureCpuSamples is TRUE then this must be 1000u, 4000, or 8000u. It's otherwise ignored.\r\n\r\nBOOL CaptureFileIO;\r\n\r\nBOOL CaptureVirtualAllocEvents;\r\nBOOL CaptureHeapAllocEvents;\r\nBOOL CaptureXMemEvents; \/\/ ignored in PIX on Windows\r\nBOOL CapturePixMemEvents; \/\/ ignored in PIX on Windows<\/code><\/pre>\n<p>&nbsp;<\/p>\n<p><strong>HRESULT WINAPI PIXBeginCapture2(DWORD captureFlags, _In_opt_ const PPIXCaptureParameters captureParameters)<\/strong><\/p>\n<p>This API is functionally equivalent to PIXBeginCapture. It exists for compatibility reasons.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>HRESULT WINAPI PIXEndCapture(BOOL discard)<\/strong><\/p>\n<p>This API immediately terminates any in-progress GPU Capture or Timing Capture started via PIXBeginCapture(). PIX on Windows ignores the discard parameter.<\/p>\n<p>If you&#8217;re taking a GPU Capture then you may want to wait for all pending GPU work to finish executing before calling this API, to ensure that you capture everything that you expect to capture.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>HRESULT WINAPI PIXGpuCaptureNextFrames(PCWSTR fileName, UINT32 numFrames)<\/strong><\/p>\n<p><em>*GPU Capture only*<\/em><\/p>\n<p>This API enqueues a Present-to-Present GPU capture that will begin next time a qualifying Present() call is made. This is equivalent to pressing the Print-Screen key or hitting the capture button in the PIX UI.<\/p>\n<p>The filename should use the .wpix file extension.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>HRESULT WINAPI PIXSetTargetWindow(HWND hwnd)<\/strong><\/p>\n<p><em>*GPU Capture only*<\/em><\/p>\n<p>This API tells PIX which target window the application is interesting in capturing. After calling this API, PIX will only start or stop Present-to-Present GPU Captures when the application presents the target HWND. Present() calls to other HWNDs will be captured when applicable, but they will not start or stop capture.<\/p>\n<p>PIXSetTargetWindow is useful in multi-window applications such as game engine editors, where PIX users typically want to capture one particular window.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>HRESULT WINAPI PIXSetHUDOptions(PIXHUDOptions hudOptions)<\/strong><\/p>\n<p><em>*GPU Capture only*<\/em><\/p>\n<p>This API is used to set different display options for the PIX overlay. Valid options are<\/p>\n<ul type=\"disc\">\n<li><span data-ogsc=\"darkslategray\">PIX_HUD_SHOW_ON_ALL_WINDOWS:\u00a0<\/span>Overlay displayed on the top left all the windows created by the test app.<\/li>\n<li><span data-ogsc=\"darkslategray\">PIX_HUD_SHOW_ON_TARGET_WINDOW_ONLY:\u00a0<\/span>Overlay should only be seen on the target window (set using<span data-ogsc=\"darkslategray\">\u00a0<\/span><span data-ogsc=\"black\">PIXSetTargetWindow<\/span>)<\/li>\n<li><span data-ogsc=\"darkslategray\">PIX_HUD_SHOW_ON_NO_WINDOWS:\u00a0<\/span>Overlay should not be seen on any window created by the test app.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><strong>HRESULT WINAPI PIXForceD3D11on12()<\/strong><\/p>\n<p><em>*GPU Capture only*<\/em><\/p>\n<p>This API allows a D3D11 app to be captured by PIX using the 11on12 mapping layer<\/p>\n<ul type=\"disc\">\n<li><b>Important:<\/b>\u00a0Call the function before a D3D11 device is created.<\/li>\n<li>Can be used to launch and take captures of a D3D11 app (leaving the Force11on12 checkbox empty).<\/li>\n<li>Can also be used to attach to a running D3D11 app.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3>Legacy GPU Capture APIs<\/h3>\n<p>GPU Captures can also be taken via the IDXGraphicsAnalysis interface. The methods on this interface will only work after launching your application through PIX\/pixtool, or after attaching PIX to your application.<\/p>\n<p>The interface is defined in DXProgrammableCapture.h header, included with the Windows 10 SDK.<\/p>\n<pre class=\"prettyprint\">    #include &lt;DXProgrammableCapture.h&gt;<\/pre>\n<p>Alternatively, here is the definition:<\/p>\n<pre class=\"prettyprint\">\u00a0\u00a0\u00a0 interface DECLSPEC_UUID(\"9f251514-9d4d-4902-9d60-18988ab7d4b5\") DECLSPEC_NOVTABLE\r\n\r\n\u00a0\u00a0\u00a0 IDXGraphicsAnalysis : public IUnknown\r\n\r\n\u00a0\u00a0\u00a0 {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 STDMETHOD_(void, BeginCapture)() PURE;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 STDMETHOD_(void, EndCapture)() PURE;\r\n\r\n\u00a0\u00a0\u00a0 };<\/pre>\n<p>IDXGraphicsAnalysis can be retrieved using DXGIGetDebugInterface1:<\/p>\n<pre class=\"prettyprint\">\u00a0\u00a0\u00a0 ComPtr&lt;IDXGraphicsAnalysis&gt; ga;\r\n\r\n\u00a0\u00a0\u00a0 HRESULT hr = DXGIGetDebugInterface1(0, IID_PPV_ARGS(&amp;ga));\r\n\r\n\u00a0\u00a0\u00a0 \/\/ hr will be E_NOINTERFACE if not attached for GPU capture<\/pre>\n<p>Once you have the IDXGraphicsAnalysis*, then you can call BeginCapture and EndCapture on it to control when a GPU capture is taken:<\/p>\n<pre class=\"prettyprint\"> \u00a0\u00a0 ga-&gt;BeginCapture();\r\n\r\n\u00a0\u00a0\u00a0 \/\/ Perform rendering work\r\n\r\n\u00a0\u00a0\u00a0 \/\/ ...\r\n\r\n\u00a0\u00a0\u00a0 ga-&gt;EndCapture();<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>PIX allows applications to take and configure GPU Captures programmatically using various APIs documented here. Starting with PIX on Windows version 2303.02, Timing Captures can also be taken programmatically. Using pix3.h pix3.h is included in the WinPixEventRuntime, which is documented here. &nbsp; GPU Capture APIs in pix3.h Before using the pix3 GPU Capture APIs, you [&hellip;]<\/p>\n","protected":false},"author":1719,"featured_media":4769,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-3055","page","type-page","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/pages\/3055","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/users\/1719"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/comments?post=3055"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/pages\/3055\/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=3055"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}