@@ -39,6 +39,10 @@ PixCaptureHelper::PixCaptureHelper(PixCaptureType captureType, std::string_view
39
39
{
40
40
m_gpuCaptureLibrary.reset (PIXLoadLatestWinPixGpuCapturerLibrary ());
41
41
}
42
+ else if (captureType == PixCaptureType::ProgrammaticTiming)
43
+ {
44
+ m_timingCaptureLibrary.reset (PIXLoadLatestWinPixTimingCapturerLibrary ());
45
+ }
42
46
#endif
43
47
}
44
48
@@ -61,7 +65,9 @@ HRESULT PixCaptureHelper::BeginCapturableWork()
61
65
{
62
66
case PixCaptureType::ProgrammaticTiming:
63
67
{
64
- #ifdef _GAMING_XBOX
68
+ #if defined(PIX_NONE)
69
+ return E_NOTIMPL;
70
+ #elif defined(_GAMING_XBOX)
65
71
auto captureName = m_captureName + L" .pevt" ;
66
72
PIXCaptureParameters captureParams = {};
67
73
captureParams.TimingCaptureParameters .CaptureGpuTiming = TRUE ;
@@ -73,8 +79,26 @@ HRESULT PixCaptureHelper::BeginCapturableWork()
73
79
captureParams.TimingCaptureParameters .MaximumToolingMemorySizeMb = 4096 ;
74
80
return PIXBeginCapture (PIX_CAPTURE_TIMING, &captureParams);
75
81
#else
76
- // There is currently no programmatic API for timing captures on Windows.
77
- return E_NOTIMPL;
82
+ if (!m_timingCaptureLibrary)
83
+ {
84
+ throw std::runtime_error (" The WinPix Timing capturer library was not found. Ensure that PIX version 2303.02 or later is installed." );
85
+ }
86
+ auto captureName = m_captureName + L" .wpix" ;
87
+
88
+ PIXCaptureParameters captureParams = {};
89
+ captureParams.TimingCaptureParameters .FileName = captureName.c_str ();
90
+ captureParams.TimingCaptureParameters .CaptureGpuTiming = TRUE ;
91
+ captureParams.TimingCaptureParameters .CaptureCallstacks = TRUE ;
92
+ captureParams.TimingCaptureParameters .CaptureCpuSamples = TRUE ;
93
+ captureParams.TimingCaptureParameters .CpuSamplesPerSecond = 4000 ;
94
+ captureParams.TimingCaptureParameters .CaptureStorage = PIXCaptureParameters::Memory;
95
+ captureParams.TimingCaptureParameters .MaximumToolingMemorySizeMb = 4096 ;
96
+ HRESULT hr = PIXBeginCapture (PIX_CAPTURE_TIMING, &captureParams);
97
+ if (hr == E_ACCESSDENIED)
98
+ {
99
+ throw std::runtime_error (" E_ACCESSDENIED while attempting to begin PIX timing capture. Timing capture requires elevated privileges." );
100
+ }
101
+ return hr;
78
102
#endif
79
103
}
80
104
@@ -95,7 +119,7 @@ HRESULT PixCaptureHelper::BeginCapturableWork()
95
119
96
120
// PIXBeginCapture can only be used for GPU captures on Windows.
97
121
PIXCaptureParameters captureParams = {};
98
- captureParams.TimingCaptureParameters .FileName = captureName.c_str ();
122
+ captureParams.GpuCaptureParameters .FileName = captureName.c_str ();
99
123
return PIXBeginCapture (PIX_CAPTURE_GPU, &captureParams);
100
124
#endif
101
125
}
@@ -124,7 +148,9 @@ HRESULT PixCaptureHelper::EndCapturableWork()
124
148
{
125
149
case PixCaptureType::ProgrammaticTiming:
126
150
{
127
- #if defined(_GAMING_XBOX)
151
+ #if defined(PIX_NONE)
152
+ return E_NOTIMPL;
153
+ #elif defined(_GAMING_XBOX)
128
154
HRESULT hr;
129
155
do
130
156
{
@@ -137,8 +163,9 @@ HRESULT PixCaptureHelper::EndCapturableWork()
137
163
138
164
return hr;
139
165
#else
140
- // There is currently no programmatic API for timing captures on Windows.
141
- return E_NOTIMPL;
166
+ // PIX on Windows ignores the discard parameter, and will flush internally,
167
+ // no need for the loop xbox needs above.
168
+ return PIXEndCapture (/* discard*/ FALSE );
142
169
#endif
143
170
}
144
171
0 commit comments