Path: blob/master/dep/winpixeventruntime/include/WinPixEventRuntime/pix3_win.h
4261 views
// Copyright (c) Microsoft Corporation. All rights reserved.12/*==========================================================================;3*4* Copyright (C) Microsoft Corporation. All Rights Reserved.5*6* File: PIX3_win.h7* Content: PIX include file8* Don't include this file directly - use pix3.h9*10****************************************************************************/1112#pragma once1314#ifndef _PIX3_H_15#error Don't include this file directly - use pix3.h16#endif1718#ifndef _PIX3_WIN_H_19#define _PIX3_WIN_H_2021// PIXEventsThreadInfo is defined in PIXEventsCommon.h22struct PIXEventsThreadInfo;2324extern "C" PIXEventsThreadInfo* WINAPI PIXGetThreadInfo() noexcept;2526#if defined(USE_PIX) && defined(USE_PIX_SUPPORTED_ARCHITECTURE)27// Notifies PIX that an event handle was set as a result of a D3D12 fence being signaled.28// The event specified must have the same handle value as the handle29// used in ID3D12Fence::SetEventOnCompletion.30extern "C" void WINAPI PIXNotifyWakeFromFenceSignal(_In_ HANDLE event);3132// Notifies PIX that a block of memory was allocated33extern "C" void WINAPI PIXRecordMemoryAllocationEvent(USHORT allocatorId, void* baseAddress, size_t size, UINT64 metadata);3435// Notifies PIX that a block of memory was freed36extern "C" void WINAPI PIXRecordMemoryFreeEvent(USHORT allocatorId, void* baseAddress, size_t size, UINT64 metadata);3738#else3940// Eliminate these APIs when not using PIX41inline void PIXRecordMemoryAllocationEvent(USHORT, void*, size_t, UINT64) {}42inline void PIXRecordMemoryFreeEvent(USHORT, void*, size_t, UINT64) {}4344#endif4546// The following defines denote the different metadata values that have been used47// by tools to denote how to parse pix marker event data. The first two values48// are legacy values.49#define WINPIX_EVENT_UNICODE_VERSION 050#define WINPIX_EVENT_ANSI_VERSION 151#define WINPIX_EVENT_PIX3BLOB_VERSION 25253#define D3D12_EVENT_METADATA WINPIX_EVENT_PIX3BLOB_VERSION5455__forceinline UINT64 PIXGetTimestampCounter()56{57LARGE_INTEGER time = {};58QueryPerformanceCounter(&time);59return static_cast<UINT64>(time.QuadPart);60}6162enum PIXHUDOptions63{64PIX_HUD_SHOW_ON_ALL_WINDOWS = 0x1,65PIX_HUD_SHOW_ON_TARGET_WINDOW_ONLY = 0x2,66PIX_HUD_SHOW_ON_NO_WINDOWS = 0x467};68DEFINE_ENUM_FLAG_OPERATORS(PIXHUDOptions);6970#if defined(USE_PIX_SUPPORTED_ARCHITECTURE) && defined(USE_PIX)7172#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)7374#include <shlobj.h>75#include <strsafe.h>76#include <knownfolders.h>77#include <shellapi.h>7879#define PIXERRORCHECK(value) do { \80if (FAILED(value)) \81return nullptr; \82} while(0)8384namespace PixImpl85{86#ifndef PIX3_WIN_UNIT_TEST8788__forceinline BOOL GetModuleHandleExW(89DWORD dwFlags,90LPCWSTR lpModuleName,91HMODULE* phModule)92{93return ::GetModuleHandleExW(dwFlags, lpModuleName, phModule);94}9596__forceinline HRESULT SHGetKnownFolderPath(97REFKNOWNFOLDERID rfid,98DWORD dwFlags,99HANDLE hToken,100PWSTR* ppszPath)101{102return ::SHGetKnownFolderPath(rfid, dwFlags, hToken, ppszPath);103}104105__forceinline void CoTaskMemFree(LPVOID pv)106{107return ::CoTaskMemFree(pv);108}109110__forceinline HANDLE FindFirstFileW(111LPCWSTR lpFileName,112LPWIN32_FIND_DATAW lpFindFileData)113{114return ::FindFirstFileW(lpFileName, lpFindFileData);115}116117__forceinline DWORD GetFileAttributesW(LPCWSTR lpFileName)118{119return ::GetFileAttributesW(lpFileName);120}121122__forceinline BOOL FindNextFileW(123HANDLE hFindFile,124LPWIN32_FIND_DATAW lpFindFileData)125{126return ::FindNextFileW(hFindFile, lpFindFileData);127}128129__forceinline BOOL FindClose(HANDLE hFindFile)130{131return ::FindClose(hFindFile);132}133134__forceinline HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, DWORD flags)135{136return ::LoadLibraryExW(lpLibFileName, NULL, flags);137}138139#endif // !PIX3_WIN_UNIT_TESTS140141__forceinline void * GetGpuCaptureFunctionPtr(LPCSTR fnName) noexcept142{143HMODULE module = GetModuleHandleW(L"WinPixGpuCapturer.dll");144if (module == NULL)145{146return nullptr;147}148149auto fn = (void*)GetProcAddress(module, fnName);150if (fn == nullptr)151{152return nullptr;153}154155return fn;156}157158__forceinline void* GetTimingCaptureFunctionPtr(LPCSTR fnName) noexcept159{160HMODULE module = GetModuleHandleW(L"WinPixTimingCapturer.dll");161if (module == NULL)162{163return nullptr;164}165166auto fn = (void*)GetProcAddress(module, fnName);167if (fn == nullptr)168{169return nullptr;170}171172return fn;173}174175__forceinline HMODULE PIXLoadLatestCapturerLibrary(wchar_t const* capturerDllName, DWORD flags)176{177HMODULE libHandle{};178179if (PixImpl::GetModuleHandleExW(0, capturerDllName, &libHandle))180{181return libHandle;182}183184LPWSTR programFilesPath = nullptr;185if (FAILED(PixImpl::SHGetKnownFolderPath(FOLDERID_ProgramFiles, KF_FLAG_DEFAULT, NULL, &programFilesPath)))186{187PixImpl::CoTaskMemFree(programFilesPath);188return nullptr;189}190191wchar_t pixSearchPath[MAX_PATH];192193if (FAILED(StringCchCopyW(pixSearchPath, MAX_PATH, programFilesPath)))194{195PixImpl::CoTaskMemFree(programFilesPath);196return nullptr;197}198PixImpl::CoTaskMemFree(programFilesPath);199200PIXERRORCHECK(StringCchCatW(pixSearchPath, MAX_PATH, L"\\Microsoft PIX\\*"));201202WIN32_FIND_DATAW findData;203bool foundPixInstallation = false;204wchar_t newestVersionFound[MAX_PATH];205wchar_t output[MAX_PATH];206wchar_t possibleOutput[MAX_PATH];207208HANDLE hFind = PixImpl::FindFirstFileW(pixSearchPath, &findData);209if (hFind != INVALID_HANDLE_VALUE)210{211do212{213if (((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) &&214(findData.cFileName[0] != '.'))215{216if (!foundPixInstallation || wcscmp(newestVersionFound, findData.cFileName) <= 0)217{218// length - 1 to get rid of the wildcard character in the search path219PIXERRORCHECK(StringCchCopyNW(possibleOutput, MAX_PATH, pixSearchPath, wcslen(pixSearchPath) - 1));220PIXERRORCHECK(StringCchCatW(possibleOutput, MAX_PATH, findData.cFileName));221PIXERRORCHECK(StringCchCatW(possibleOutput, MAX_PATH, L"\\"));222PIXERRORCHECK(StringCchCatW(possibleOutput, MAX_PATH, capturerDllName));223224DWORD result = PixImpl::GetFileAttributesW(possibleOutput);225226if (result != INVALID_FILE_ATTRIBUTES && !(result & FILE_ATTRIBUTE_DIRECTORY))227{228foundPixInstallation = true;229PIXERRORCHECK(StringCchCopyW(newestVersionFound, _countof(newestVersionFound), findData.cFileName));230PIXERRORCHECK(StringCchCopyW(output, _countof(possibleOutput), possibleOutput));231}232}233}234} while (PixImpl::FindNextFileW(hFind, &findData) != 0);235}236237PixImpl::FindClose(hFind);238239if (!foundPixInstallation)240{241SetLastError(ERROR_FILE_NOT_FOUND);242return nullptr;243}244245return PixImpl::LoadLibraryExW(output, flags);246}247}248249#undef PIXERRORCHECK250251__forceinline HMODULE PIXLoadLatestWinPixGpuCapturerLibrary()252{253return PixImpl::PIXLoadLatestCapturerLibrary(254L"WinPixGpuCapturer.dll",255LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);256}257258__forceinline HMODULE PIXLoadLatestWinPixTimingCapturerLibrary()259{260return PixImpl::PIXLoadLatestCapturerLibrary(261L"WinPixTimingCapturer.dll",262LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);263}264265__forceinline HRESULT WINAPI PIXSetTargetWindow(HWND hwnd)266{267typedef void(WINAPI* SetGlobalTargetWindowFn)(HWND);268269auto fn = (SetGlobalTargetWindowFn)PixImpl::GetGpuCaptureFunctionPtr("SetGlobalTargetWindow");270if (fn == nullptr)271{272return HRESULT_FROM_WIN32(GetLastError());273}274275fn(hwnd);276return S_OK;277}278279__forceinline HRESULT WINAPI PIXGpuCaptureNextFrames(PCWSTR fileName, UINT32 numFrames)280{281typedef HRESULT(WINAPI* CaptureNextFrameFn)(PCWSTR, UINT32);282283auto fn = (CaptureNextFrameFn)PixImpl::GetGpuCaptureFunctionPtr("CaptureNextFrame");284if (fn == nullptr)285{286return HRESULT_FROM_WIN32(GetLastError());287}288289return fn(fileName, numFrames);290}291292extern "C" __forceinline HRESULT WINAPI PIXBeginCapture2(DWORD captureFlags, _In_opt_ const PPIXCaptureParameters captureParameters)293{294if (captureFlags == PIX_CAPTURE_GPU)295{296typedef HRESULT(WINAPI* BeginProgrammaticGpuCaptureFn)(const PPIXCaptureParameters);297298auto fn = (BeginProgrammaticGpuCaptureFn)PixImpl::GetGpuCaptureFunctionPtr("BeginProgrammaticGpuCapture");299if (fn == nullptr)300{301return HRESULT_FROM_WIN32(GetLastError());302}303304return fn(captureParameters);305}306else if (captureFlags == PIX_CAPTURE_TIMING)307{308typedef HRESULT(WINAPI* BeginProgrammaticTimingCaptureFn)(void const*, UINT64);309310auto fn = (BeginProgrammaticTimingCaptureFn)PixImpl::GetTimingCaptureFunctionPtr("BeginProgrammaticTimingCapture");311if (fn == nullptr)312{313return HRESULT_FROM_WIN32(GetLastError());314}315316return fn(&captureParameters->TimingCaptureParameters, sizeof(captureParameters->TimingCaptureParameters));317}318else319{320return E_NOTIMPL;321}322}323324extern "C" __forceinline HRESULT WINAPI PIXEndCapture(BOOL discard)325{326UNREFERENCED_PARAMETER(discard);327328// We can't tell if the user wants to end a GPU Capture or a Timing Capture.329// The user shouldn't have both WinPixGpuCapturer and WinPixTimingCapturer loaded in the process though,330// so we can just look for one of them and call it.331typedef HRESULT(WINAPI* EndProgrammaticGpuCaptureFn)(void);332auto gpuFn = (EndProgrammaticGpuCaptureFn)PixImpl::GetGpuCaptureFunctionPtr("EndProgrammaticGpuCapture");333if (gpuFn != NULL)334{335return gpuFn();336}337338typedef HRESULT(WINAPI* EndProgrammaticTimingCaptureFn)(BOOL);339auto timingFn = (EndProgrammaticTimingCaptureFn)PixImpl::GetTimingCaptureFunctionPtr("EndProgrammaticTimingCapture");340if (timingFn != NULL)341{342return timingFn(discard);343}344345return HRESULT_FROM_WIN32(GetLastError());346}347348__forceinline HRESULT WINAPI PIXForceD3D11On12()349{350typedef HRESULT (WINAPI* ForceD3D11On12Fn)(void);351352auto fn = (ForceD3D11On12Fn)PixImpl::GetGpuCaptureFunctionPtr("ForceD3D11On12");353if (fn == NULL)354{355return HRESULT_FROM_WIN32(GetLastError());356}357358return fn();359}360361__forceinline HRESULT WINAPI PIXSetHUDOptions(PIXHUDOptions hudOptions)362{363typedef HRESULT(WINAPI* SetHUDOptionsFn)(PIXHUDOptions);364365auto fn = (SetHUDOptionsFn)PixImpl::GetGpuCaptureFunctionPtr("SetHUDOptions");366if (fn == NULL)367{368return HRESULT_FROM_WIN32(GetLastError());369}370371return fn(hudOptions);372}373374__forceinline bool WINAPI PIXIsAttachedForGpuCapture()375{376typedef bool(WINAPI* GetIsAttachedToPixFn)(void);377auto fn = (GetIsAttachedToPixFn)PixImpl::GetGpuCaptureFunctionPtr("GetIsAttachedToPix");378if (fn == NULL)379{380OutputDebugStringW(L"WinPixEventRuntime error: Mismatched header/dll. Please ensure that pix3.h and WinPixGpuCapturer.dll match");381return false;382}383384return fn();385}386387__forceinline HINSTANCE WINAPI PIXOpenCaptureInUI(PCWSTR fileName)388{389return ShellExecuteW(0, 0, fileName, 0, 0, SW_SHOW);390}391392#else393__forceinline HMODULE PIXLoadLatestWinPixGpuCapturerLibrary()394{395return nullptr;396}397__forceinline HMODULE PIXLoadLatestWinPixTimingCapturerLibrary()398{399return nullptr;400}401__forceinline HRESULT WINAPI PIXSetTargetWindow(HWND)402{403return E_NOTIMPL;404}405406__forceinline HRESULT WINAPI PIXGpuCaptureNextFrames(PCWSTR, UINT32)407{408return E_NOTIMPL;409}410extern "C" __forceinline HRESULT WINAPI PIXBeginCapture2(DWORD, _In_opt_ const PPIXCaptureParameters)411{412return E_NOTIMPL;413}414extern "C" __forceinline HRESULT WINAPI PIXEndCapture(BOOL)415{416return E_NOTIMPL;417}418__forceinline HRESULT WINAPI PIXForceD3D11On12()419{420return E_NOTIMPL;421}422__forceinline HRESULT WINAPI PIXSetHUDOptions(PIXHUDOptions)423{424return E_NOTIMPL;425}426__forceinline bool WINAPI PIXIsAttachedForGpuCapture()427{428return false;429}430__forceinline HINSTANCE WINAPI PIXOpenCaptureInUI(PCWSTR)431{432return 0;433}434#endif // WINAPI_PARTITION435436#endif // USE_PIX_SUPPORTED_ARCHITECTURE || USE_PIX437438#endif //_PIX3_WIN_H_439440441