{"id":1435,"date":"2016-10-23T23:20:20","date_gmt":"2016-10-23T23:20:20","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/pix\/?page_id=1435"},"modified":"2024-08-22T13:40:58","modified_gmt":"2024-08-22T20:40:58","slug":"winpixeventruntime","status":"publish","type":"page","link":"https:\/\/devblogs.microsoft.com\/pix\/winpixeventruntime\/","title":{"rendered":"WinPixEventRuntime"},"content":{"rendered":"<p>PIX events are used to instrument your game, labeling regions of CPU or GPU work and marking important occurrences.\u00a0 Including this instrumentation while developing the game can make PIX captures far nicer to work with.<\/p>\n<p>An &#8220;event&#8221; represents a region of time &#8211; so an event has a begin and an end.\u00a0 A &#8220;marker&#8221; is used to represent a single point in time.<\/p>\n<h2>Installation<\/h2>\n<p>The PIX event runtime is distributed as a <a href=\"https:\/\/www.nuget.org\/packages\/WinPixEventRuntime\">NuGet package<\/a>.\u00a0 If your project builds in Visual Studio, you can use Visual Studio to add this package:<\/p>\n<ol>\n<li>Right-click on the project in <em>Solution Explorer.<\/em><\/li>\n<li><em>Manage NuGet Packages.<\/em><\/li>\n<li>Select the <em>Browse<\/em> tab.<\/li>\n<li>Type \u201cWinPixEventRuntime\u201d into the search box.<\/li>\n<li>Select the package and click <em>Install<\/em>.<\/li>\n<li>You can now #include &#8220;pix3.h&#8221; to access the PIX event APIs.<\/li>\n<\/ol>\n<p>If your project uses some other build technology than Visual Studio, you can manually consume the NuGet package contents:<\/p>\n<ol>\n<li>Click the <em>Download<\/em> link on <a href=\"https:\/\/www.nuget.org\/packages\/WinPixEventRuntime\">https:\/\/www.nuget.org\/packages\/WinPixEventRuntime<\/a><\/li>\n<li>Rename the .nupkg file to a .zip extension, then extract its contents.<\/li>\n<li>Include the header file: <em>Include\\WinPixEventRuntime\\pix3.h<\/em><\/li>\n<li>Link with the library:\n<ul>\n<li>For desktop apps: <em>bin\\WinPixEventRuntime.lib<\/em><\/li>\n<li>For Universal Windows Platform (UWP) apps: <em>bin\\WinPixEventRuntime_UAP.lib<\/em><\/li>\n<\/ul>\n<\/li>\n<li>Place the corresponding .dll next to your game.<\/li>\n<\/ol>\n<p>PIX instrumentation is only enabled if one of the preprocessor symbols USE_PIX, DBG, _DEBUG, PROFILE, or PROFILE_BUILD is defined.\u00a0 Otherwise the marker APIs compile out to nothing, which is typically what you want for final release builds of the game.\u00a0 It is often useful to maintain an intermediate build flavor for profiling purposes, which is fully optimized and leaves out self-checks such as ASSERT, but does include the PIX marker instrumentation.\u00a0 To do this, define one of the symbols USE_PIX or PROFILE before including pix3.h.<\/p>\n<p>Note that the Windows SDK provides an older header named pix.h.\u00a0 This defines similar functions to pix3.h, but is obsolete and not compatible with PIX.<\/p>\n<h2>API Reference<\/h2>\n<h2>PIXBeginEvent<\/h2>\n<p>PIXBeginEvent marks the start of a user-defined region of CPU or GPU work.\u00a0 There are overloads of PIXBeginEvent that support different types of strings and CPU and GPU events. Use PIXEndEvent to mark the end of the region. The paired calls to PIXBeginEvent and PIXEndEvent must be made from the same thread.<\/p>\n<pre class=\"lang:c++ decode:true\">\/\/ CPU only\r\nvoid PIXBeginEvent(UINT64 color, char const* formatString, ...)\r\nvoid PIXBeginEvent(UINT64 color, wchar_t const* formatString, ...)\r\n\r\n\/\/ GPU and CPU\r\nvoid PIXBeginEvent(ID3D12CommandList* commandList, UINT64 color, char const* formatString, ...)\r\nvoid PIXBeginEvent(ID3D12CommandList* commandList, UINT64 color, wchar_t const* formatString, ...)\r\nvoid PIXBeginEvent(ID3D12CommandQueue* commandQueue, UINT64 color, char const* formatString, ...)\r\nvoid PIXBeginEvent(ID3D12CommandQueue* commandQueue, UINT64 color, wchar_t const* formatString, ...)\r\n<\/pre>\n<p>The GPU overloads also start an implicit CPU region.<\/p>\n<h2>PIXEndEvent<\/h2>\n<p>PIXEndEvent marks the end of a user-defined region of CPU or GPU work. There are overloads of PIXEndEvent that support different types of CPU and GPU events. Note that a GPU region that was started on a command list may be ended on a command list or a command queue, and vice versa.<\/p>\n<pre class=\"lang:c++ decode:true\">\/\/ CPU only\r\nvoid PIXEndEvent()\r\n        \r\n\/\/ GPU and CPU\r\nvoid PIXEndEvent(ID3D12CommandList* commandList)\r\nvoid PIXEndEvent(ID3D12CommandQueue* commandQueue)<\/pre>\n<p>The GPU overloads also end an implicit CPU region.<\/p>\n<h2>PIXSetMarker<\/h2>\n<p>PIXSetMarker inserts a user-defined marker into the CPU or GPU timeline:<\/p>\n<pre class=\"lang:c++ decode:true\"> \/\/ CPU\r\nvoid PIXSetMarker(UINT64 color, char const* formatString, ...)\r\nvoid PIXSetMarker(UINT64 color, wchar_t const* formatString, ...)\r\n\r\n\/\/ GPU and CPU\r\nvoid PIXSetMarker(ID3D12GraphicsCommandList* commandList, UINT64 color, char const* formatString, ...)\r\nvoid PIXSetMarker(ID3D12GraphicsCommandList* commandList, UINT64 color, wchar_t const* formatString, ...)\r\nvoid PIXSetMarker(ID3D12CommandQueue* commandQueue, UINT64 color, char const* formatString, ...)\r\nvoid PIXSetMarker(ID3D12CommandQueue* commandQueue, UINT64 color, wchar_t const* formatString, ...)<\/pre>\n<h2>PIXScopedEvent<\/h2>\n<p>The PIXScopedEvent macro has the same overloads as PixBeginEvent, but will automatically issue a matching PixEndEvent call at the end of the C++ code scope where it is used:<\/p>\n<pre class=\"lang:c++ decode:true\">PIXScopedEvent(UINT64 color, char const* formatString, ...)\r\nPIXScopedEvent(UINT64 color, wchar_t const* formatString, ...)\r\nPIXScopedEvent(ID3D12GraphicsCommandList* commandList, UINT64 color, char const* formatString, ...)\r\nPIXScopedEvent(ID3D12GraphicsCommandList* commandList, UINT64 color, wchar_t const* formatString, ...)\r\nPIXScopedEvent(ID3D12CommandQueue* commandQueue, UINT64 color, char const* formatString, ...)\r\nPIXScopedEvent(ID3D12CommandQueue* commandQueue, UINT64 color, wchar_t const* formatString, ...)<\/pre>\n<h2>PIXReportCounter<\/h2>\n<p>PIXReportCounter allows a custom value to be graphed in System Monitor or timing captures.<\/p>\n<pre class=\"lang:c++ decode:true\">void PIXReportCounter(wchar_t const* name, float value)<\/pre>\n<p>Note that PIXReportCounter does not has a <tt>char const*<\/tt> overload.<\/p>\n<h2>PIXNotifyWakeFromFenceSignal<\/h2>\n<p><a href=\"http:\/\/devblogs.microsoft.com\/pix\/timing-captures\">Timing captures<\/a> can show when a thread wakes up as the result of a fence being signaled. This needs some help from the application in the form of PIXNotifyWakeFromFenceSignal. This notifies PIX that an event handle was set as a result of a D3D12 fence being signaled. The event specified must have the same handle value as the handle used in <tt>ID3D12Fence::SetEventOnCompletion<\/tt>.<\/p>\n<pre class=\"lang:c++ decode:true\">void PIXNotifyWakeFromFenceSignal(HANDLE event)<\/pre>\n<h2>Color<\/h2>\n<p>The color parameter controls how the event will be displayed in timeline lanes when it appears in the PIX timing capture user interface.\u00a0 Suitable values can be obtained from one of these helpers, or you can pass in a raw DWORD noting that the format is ARGB and the alpha channel value must be 0xff:<\/p>\n<pre class=\"lang:c++ decode:true\">\/\/ Returns a color for a PIX event or marker from the specified red, green and blue values\r\n INT PIX_COLOR(BYTE r, BYTE g, BYTE b)\r\n\r\n\/\/ Returns an arbitrary color value for the given index.\r\n\/\/ PIX allocates a unique color for each index.\r\nUINT PIX_COLOR_INDEX(BYTE i)<\/pre>\n<h2>Formatted Strings<\/h2>\n<p>In order to minimize instrumentation overhead, the PIXBeginEvent and PIXSetMarker functions directly save their format string and format parameters instead of formatting the string at runtime. Formatting is then done when reading the capture file in PIX. Use 16-byte aligned strings (preferable) or 8-byte aligned strings to get the best performance. To print a char* or wchar_t* as a pointer using %p format specifier, cast the pointer to void* when passing it to these functions.<\/p>\n<h2>Other functions<\/h2>\n<p>PIX on Windows supports programmatic capture APIs (such as PIXBeginCapture) for GPU Captures. Please see this <a href=\"https:\/\/devblogs.microsoft.com\/pix\/programmatic-capture\/\" target=\"_blank\" rel=\"noopener\">page <\/a>for more details.<\/p>\n<h2><a id=\"abiusage\"><\/a>ABI Usage<\/h2>\n<p>Most of the implementation of PIX markers is in the header file with the DLL providing support functionality. The stable interface though is in the header file. If for some reason it is necessary to use a stable ABI then these entry points are available. These have a stronger compatability guarantee than the other WinPixEventRuntime.dll exports.<\/p>\n<p><em>Most users should continue to use pix3.h. This will provide richer and more optimized functionality.<\/em><\/p>\n<p>The source snippet below is subject to the <a href=\"https:\/\/opensource.org\/licenses\/MIT\">MIT license<\/a><\/p>\n<p>Use LoadLibrary to load the dll and GetProcAddress to access the exports:<\/p>\n<pre class=\"lang:c++ decode:true\">typedef void(WINAPI* BeginEventOnCommandList)(ID3D12GraphicsCommandList* commandList, UINT64 color, _In_ PCSTR formatString);\r\ntypedef void(WINAPI* EndEventOnCommandList)(ID3D12GraphicsCommandList* commandList);\r\ntypedef void(WINAPI* SetMarkerOnCommandList)(ID3D12GraphicsCommandList* commandList, UINT64 color, _In_ PCSTR formatString);\r\n\r\nHMODULE module = LoadLibrary(L\"WinPixEventRuntime.dll\");\r\n\r\nBeginEventOnCommandList pixBeginEventOnCommandList = (BeginEventOnCommandList)GetProcAddress(module, \"PIXBeginEventOnCommandList\");\r\nEndEventOnCommandList   pixEndEventOnCommandList   = (EndEventOnCommandList)GetProcAddress(module, \"PIXEndEventOnCommandList\");\r\nSetMarkerOnCommandList  pixSetMarkerOnCommandList  = (SetMarkerOnCommandList)GetProcAddress(module, \"PIXSetMarkerOnCommandList\");\r\n<\/pre>\n<p>Error handling and more careful resource management is left as an exercise for the reader.<\/p>\n<h2>Release History<\/h2>\n<ul>\n<li>1.0.220810001 &#8211; Support for new programmatic APIs (HUD control, 11On12). Support for BeginEventOnCommandQueue (and similar) ABIs<\/li>\n<li>1.0.220124001 &#8211; Support for WinPixEventRuntime&#8217;s ABI (BeginEventOnCommandList etc.) in UWP.<\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/pix\/winpixeventruntime-2102-09\/\"><strong>1.0.210209001<\/strong><\/a><\/li>\n<li><strong><a href=\"https:\/\/devblogs.microsoft.com\/pix\/winpixeventruntime-2001-27\/\">1.0.200127001<\/a><\/strong><\/li>\n<li><strong>1.0.190604001<\/strong> &#8211; Fix compatability with old versions of PIX and the debug layer, fix building with \/permissive-<\/li>\n<li><strong>1.0.190510001<\/strong>\u00a0&#8211; Add ABI exports to DLL<\/li>\n<li><strong>1.0.190425002<\/strong> &#8211; ARM64 support<\/li>\n<li><strong>1.0.181206001<\/strong> &#8211; Add PIXNotifyWakeFromFenceSignal<\/li>\n<\/ul>\n<h2>Further Reading<\/h2>\n<ul>\n<li>Visit the\u00a0<a href=\"https:\/\/devblogs.microsoft.com\/directx\/landing-page\/\">DirectX Landing Page<\/a>\u00a0for more resources for DirectX developers.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>PIX events are used to instrument your game, labeling regions of CPU or GPU work and marking important occurrences.\u00a0 Including this instrumentation while developing the game can make PIX captures far nicer to work with. An &#8220;event&#8221; represents a region of time &#8211; so an event has a begin and an end.\u00a0 A &#8220;marker&#8221; is [&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-1435","page","type-page","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/pages\/1435","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=1435"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/pix\/wp-json\/wp\/v2\/pages\/1435\/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=1435"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}