diff --git a/src/dawn_native/Toggles.cpp b/src/dawn_native/Toggles.cpp index 63dcdda036..757d4ffddc 100644 --- a/src/dawn_native/Toggles.cpp +++ b/src/dawn_native/Toggles.cpp @@ -230,6 +230,13 @@ namespace dawn::native { "Enable optimizations when compiling with FXC. Disabled by default because FXC " "miscompiles in many cases when optimizations are enabled.", "https://crbug.com/dawn/1203"}}, + {Toggle::RecordDetailedTimingInTraceEvents, + {"record_detailed_timing_in_trace_events", + "Record detailed timing information in trace events at certain point. Currently the " + "timing information is recorded right before calling ExecuteCommandLists on a D3D12 " + "command queue, and the information includes system time, CPU timestamp, GPU " + "timestamp, and their frequency.", + "https://crbug.com/dawn/1264"}}, // Dummy comment to separate the }} so it is clearer what to copy-paste to add a toggle. }}; diff --git a/src/dawn_native/Toggles.h b/src/dawn_native/Toggles.h index 0fc748ffd5..5b7e97c907 100644 --- a/src/dawn_native/Toggles.h +++ b/src/dawn_native/Toggles.h @@ -61,6 +61,7 @@ namespace dawn::native { DisableR8RG8Mipmaps, UseDummyFragmentInVertexOnlyPipeline, FxcOptimizations, + RecordDetailedTimingInTraceEvents, EnumCount, InvalidEnum = EnumCount, diff --git a/src/dawn_native/d3d12/CommandRecordingContext.cpp b/src/dawn_native/d3d12/CommandRecordingContext.cpp index 6749c2c30f..f86a9301f7 100644 --- a/src/dawn_native/d3d12/CommandRecordingContext.cpp +++ b/src/dawn_native/d3d12/CommandRecordingContext.cpp @@ -12,11 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. #include "dawn_native/d3d12/CommandRecordingContext.h" + #include "dawn_native/d3d12/CommandAllocatorManager.h" #include "dawn_native/d3d12/D3D12Error.h" #include "dawn_native/d3d12/DeviceD3D12.h" #include "dawn_native/d3d12/HeapD3D12.h" #include "dawn_native/d3d12/ResidencyManagerD3D12.h" +#include "dawn_platform/DawnPlatform.h" +#include "dawn_platform/tracing/TraceEvent.h" + +#include +#include namespace dawn::native::d3d12 { @@ -74,6 +80,44 @@ namespace dawn::native::d3d12 { DAWN_TRY(device->GetResidencyManager()->EnsureHeapsAreResident( mHeapsPendingUsage.data(), mHeapsPendingUsage.size())); + if (device->IsToggleEnabled(Toggle::RecordDetailedTimingInTraceEvents)) { + uint64_t gpuTimestamp; + uint64_t cpuTimestamp; + FILETIME fileTimeNonPrecise; + SYSTEMTIME systemTimeNonPrecise; + + // Both supported since Windows 2000, have a accuracy of 1ms + GetSystemTimeAsFileTime(&fileTimeNonPrecise); + GetSystemTime(&systemTimeNonPrecise); + // Query CPU and GPU timestamps at almost the same time + device->GetCommandQueue()->GetClockCalibration(&gpuTimestamp, &cpuTimestamp); + + uint64_t gpuFrequency; + uint64_t cpuFrequency; + LARGE_INTEGER cpuFrequencyLargeInteger; + device->GetCommandQueue()->GetTimestampFrequency(&gpuFrequency); + QueryPerformanceFrequency( + &cpuFrequencyLargeInteger); // Supported since Windows 2000 + cpuFrequency = cpuFrequencyLargeInteger.QuadPart; + + std::string timingInfo = absl::StrFormat( + "UTC Time: %u/%u/%u %02u:%02u:%02u.%03u, File Time: %u, CPU " + "Timestamp: %u, GPU Timestamp: %u, CPU Tick Frequency: %u, GPU Tick Frequency: " + "%u", + systemTimeNonPrecise.wYear, systemTimeNonPrecise.wMonth, + systemTimeNonPrecise.wDay, systemTimeNonPrecise.wHour, + systemTimeNonPrecise.wMinute, systemTimeNonPrecise.wSecond, + systemTimeNonPrecise.wMilliseconds, + (static_cast(fileTimeNonPrecise.dwHighDateTime) << 32) + + fileTimeNonPrecise.dwLowDateTime, + cpuTimestamp, gpuTimestamp, cpuFrequency, gpuFrequency); + + TRACE_EVENT_INSTANT1( + device->GetPlatform(), General, + "d3d12::CommandRecordingContext::ExecuteCommandList Detailed Timing", "Timing", + timingInfo.c_str()); + } + ID3D12CommandList* d3d12CommandList = GetCommandList(); device->GetCommandQueue()->ExecuteCommandLists(1, &d3d12CommandList);