mirror of
https://github.com/wolfpld/tracy
synced 2025-05-01 13:13:53 +00:00
reworking clock calibration
This commit is contained in:
parent
6454b0bd65
commit
f9d36060df
@ -73,8 +73,37 @@ namespace tracy
|
|||||||
ID3D12Fence* m_payloadFence = nullptr;
|
ID3D12Fence* m_payloadFence = nullptr;
|
||||||
std::queue<D3D12QueryPayload> m_payloadQueue;
|
std::queue<D3D12QueryPayload> m_payloadQueue;
|
||||||
|
|
||||||
int64_t m_prevCalibration = 0;
|
UINT64 m_prevCalibrationTicksCPU = 0;
|
||||||
int64_t m_qpcToNs = int64_t{ 1000000000 / GetFrequencyQpc() };
|
|
||||||
|
void RecalibrateClocks()
|
||||||
|
{
|
||||||
|
UINT64 cpuTimestamp;
|
||||||
|
UINT64 gpuTimestamp;
|
||||||
|
if (FAILED(m_queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp)))
|
||||||
|
{
|
||||||
|
assert(false && "failed to obtain queue clock calibration counters.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t cpuDeltaTicks = cpuTimestamp - m_prevCalibrationTicksCPU;
|
||||||
|
if (cpuDeltaTicks > 0)
|
||||||
|
{
|
||||||
|
static const int64_t nanosecodsPerTick = int64_t(1000000000) / GetFrequencyQpc();
|
||||||
|
int64_t cpuDeltaNS = cpuDeltaTicks * nanosecodsPerTick;
|
||||||
|
// Save the device cpu timestamp, not the Tracy profiler timestamp:
|
||||||
|
m_prevCalibrationTicksCPU = cpuTimestamp;
|
||||||
|
|
||||||
|
cpuTimestamp = Profiler::GetTime();
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuCalibration);
|
||||||
|
MemWrite(&item->gpuCalibration.gpuTime, gpuTimestamp);
|
||||||
|
MemWrite(&item->gpuCalibration.cpuTime, cpuTimestamp);
|
||||||
|
MemWrite(&item->gpuCalibration.cpuDelta, cpuDeltaNS);
|
||||||
|
MemWrite(&item->gpuCalibration.context, GetId());
|
||||||
|
SubmitQueueItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tracy_force_inline void SubmitQueueItem(tracy::QueueItem* item)
|
tracy_force_inline void SubmitQueueItem(tracy::QueueItem* item)
|
||||||
{
|
{
|
||||||
@ -99,26 +128,6 @@ namespace tracy
|
|||||||
assert(Success && featureData.CopyQueueTimestampQueriesSupported && "Platform does not support profiling of copy queues.");
|
assert(Success && featureData.CopyQueueTimestampQueriesSupported && "Platform does not support profiling of copy queues.");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t timestampFrequency;
|
|
||||||
|
|
||||||
if (FAILED(queue->GetTimestampFrequency(×tampFrequency)))
|
|
||||||
{
|
|
||||||
assert(false && "Failed to get timestamp frequency.");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t cpuTimestamp;
|
|
||||||
uint64_t gpuTimestamp;
|
|
||||||
|
|
||||||
if (FAILED(queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp)))
|
|
||||||
{
|
|
||||||
assert(false && "Failed to get queue clock calibration.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the device cpu timestamp, not the profiler's timestamp.
|
|
||||||
m_prevCalibration = cpuTimestamp * m_qpcToNs;
|
|
||||||
|
|
||||||
cpuTimestamp = Profiler::GetTime();
|
|
||||||
|
|
||||||
D3D12_QUERY_HEAP_DESC heapDesc{};
|
D3D12_QUERY_HEAP_DESC heapDesc{};
|
||||||
heapDesc.Type = queue->GetDesc().Type == D3D12_COMMAND_LIST_TYPE_COPY ? D3D12_QUERY_HEAP_TYPE_COPY_QUEUE_TIMESTAMP : D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
|
heapDesc.Type = queue->GetDesc().Type == D3D12_COMMAND_LIST_TYPE_COPY ? D3D12_QUERY_HEAP_TYPE_COPY_QUEUE_TIMESTAMP : D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
|
||||||
heapDesc.Count = m_queryLimit;
|
heapDesc.Count = m_queryLimit;
|
||||||
@ -162,6 +171,33 @@ namespace tracy
|
|||||||
assert(false && "Failed to create payload fence.");
|
assert(false && "Failed to create payload fence.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float period = [queue]()
|
||||||
|
{
|
||||||
|
uint64_t timestampFrequency;
|
||||||
|
if (FAILED(queue->GetTimestampFrequency(×tampFrequency)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
return static_cast<float>( 1E+09 / static_cast<double>(timestampFrequency) );
|
||||||
|
}();
|
||||||
|
|
||||||
|
if (period == 0.0f)
|
||||||
|
{
|
||||||
|
assert(false && "Failed to get timestamp frequency.");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t cpuTimestamp;
|
||||||
|
uint64_t gpuTimestamp;
|
||||||
|
if (FAILED(queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp)))
|
||||||
|
{
|
||||||
|
assert(false && "Failed to get queue clock calibration.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the device cpu timestamp, not the profiler's timestamp.
|
||||||
|
m_prevCalibrationTicksCPU = cpuTimestamp;
|
||||||
|
|
||||||
|
cpuTimestamp = Profiler::GetTime();
|
||||||
|
|
||||||
// all checked: ready to roll
|
// all checked: ready to roll
|
||||||
m_contextId = GetGpuCtxCounter().fetch_add(1);
|
m_contextId = GetGpuCtxCounter().fetch_add(1);
|
||||||
|
|
||||||
@ -169,8 +205,8 @@ namespace tracy
|
|||||||
MemWrite(&item->hdr.type, QueueType::GpuNewContext);
|
MemWrite(&item->hdr.type, QueueType::GpuNewContext);
|
||||||
MemWrite(&item->gpuNewContext.cpuTime, cpuTimestamp);
|
MemWrite(&item->gpuNewContext.cpuTime, cpuTimestamp);
|
||||||
MemWrite(&item->gpuNewContext.gpuTime, gpuTimestamp);
|
MemWrite(&item->gpuNewContext.gpuTime, gpuTimestamp);
|
||||||
memset(&item->gpuNewContext.thread, 0, sizeof(item->gpuNewContext.thread));
|
MemWrite(&item->gpuNewContext.thread, decltype(item->gpuNewContext.thread)(0)); // #TODO: why 0 instead of GetThreadHandle()?
|
||||||
MemWrite(&item->gpuNewContext.period, 1E+09f / static_cast<float>(timestampFrequency));
|
MemWrite(&item->gpuNewContext.period, period);
|
||||||
MemWrite(&item->gpuNewContext.context, GetId());
|
MemWrite(&item->gpuNewContext.context, GetId());
|
||||||
MemWrite(&item->gpuNewContext.flags, GpuContextCalibration);
|
MemWrite(&item->gpuNewContext.flags, GpuContextCalibration);
|
||||||
MemWrite(&item->gpuNewContext.type, GpuContextType::Direct3D12);
|
MemWrite(&item->gpuNewContext.type, GpuContextType::Direct3D12);
|
||||||
@ -271,32 +307,7 @@ namespace tracy
|
|||||||
m_readbackBuffer->Unmap(0, nullptr);
|
m_readbackBuffer->Unmap(0, nullptr);
|
||||||
|
|
||||||
// Recalibrate to account for drift.
|
// Recalibrate to account for drift.
|
||||||
|
RecalibrateClocks();
|
||||||
uint64_t cpuTimestamp;
|
|
||||||
uint64_t gpuTimestamp;
|
|
||||||
|
|
||||||
if (FAILED(m_queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp)))
|
|
||||||
{
|
|
||||||
assert(false && "Failed to get queue clock calibration.");
|
|
||||||
}
|
|
||||||
|
|
||||||
cpuTimestamp *= m_qpcToNs;
|
|
||||||
|
|
||||||
const auto cpuDelta = cpuTimestamp - m_prevCalibration;
|
|
||||||
if (cpuDelta > 0)
|
|
||||||
{
|
|
||||||
m_prevCalibration = cpuTimestamp;
|
|
||||||
cpuTimestamp = Profiler::GetTime();
|
|
||||||
|
|
||||||
auto* item = Profiler::QueueSerial();
|
|
||||||
MemWrite(&item->hdr.type, QueueType::GpuCalibration);
|
|
||||||
MemWrite(&item->gpuCalibration.gpuTime, gpuTimestamp);
|
|
||||||
MemWrite(&item->gpuCalibration.cpuTime, cpuTimestamp);
|
|
||||||
MemWrite(&item->gpuCalibration.cpuDelta, cpuDelta);
|
|
||||||
MemWrite(&item->gpuCalibration.context, GetId());
|
|
||||||
|
|
||||||
Profiler::QueueSerialFinish();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user