Add GpuTimeSync event

Allows to resynchronise GPU and CPU timestamps during profiling.
This commit is contained in:
Ivan Molodetskikh 2023-10-22 08:03:58 +04:00
parent 3601576b3f
commit 41fc293043
7 changed files with 67 additions and 1 deletions

View File

@ -4293,6 +4293,15 @@ TRACY_API void ___tracy_emit_gpu_calibration( const struct ___tracy_gpu_calibrat
TracyLfqCommitC;
}
TRACY_API void ___tracy_emit_gpu_time_sync( const struct ___tracy_gpu_time_sync_data data )
{
TracyLfqPrepareC( tracy::QueueType::GpuTimeSync );
tracy::MemWrite( &item->gpuTimeSync.cpuTime, tracy::Profiler::GetTime() );
tracy::MemWrite( &item->gpuTimeSync.gpuTime, data.gpuTime );
tracy::MemWrite( &item->gpuTimeSync.context, data.context );
TracyLfqCommitC;
}
TRACY_API void ___tracy_emit_gpu_zone_begin_serial( const struct ___tracy_gpu_zone_begin_data data )
{
auto item = tracy::Profiler::QueueSerial();
@ -4400,6 +4409,16 @@ TRACY_API void ___tracy_emit_gpu_calibration_serial( const struct ___tracy_gpu_c
tracy::Profiler::QueueSerialFinish();
}
TRACY_API void ___tracy_emit_gpu_time_sync_serial( const struct ___tracy_gpu_time_sync_data data )
{
auto item = tracy::Profiler::QueueSerial();
tracy::MemWrite( &item->hdr.type, tracy::QueueType::GpuTimeSync );
tracy::MemWrite( &item->gpuTimeSync.cpuTime, tracy::Profiler::GetTime() );
tracy::MemWrite( &item->gpuTimeSync.gpuTime, data.gpuTime );
tracy::MemWrite( &item->gpuTimeSync.context, data.context );
tracy::Profiler::QueueSerialFinish();
}
TRACY_API int ___tracy_connected( void )
{
return tracy::GetProfiler().IsConnected();

View File

@ -9,7 +9,7 @@ namespace tracy
constexpr unsigned Lz4CompressBound( unsigned isize ) { return isize + ( isize / 255 ) + 16; }
enum : uint32_t { ProtocolVersion = 64 };
enum : uint32_t { ProtocolVersion = 65 };
enum : uint16_t { BroadcastVersion = 3 };
using lz4sz_t = uint32_t;

View File

@ -70,6 +70,7 @@ enum class QueueType : uint8_t
KeepAlive,
ThreadContext,
GpuCalibration,
GpuTimeSync,
Crash,
CrashReport,
ZoneValidation,
@ -453,6 +454,13 @@ struct QueueGpuCalibration
uint8_t context;
};
struct QueueGpuTimeSync
{
int64_t gpuTime;
int64_t cpuTime;
uint8_t context;
};
struct QueueGpuContextName
{
uint8_t context;
@ -718,6 +726,7 @@ struct QueueItem
QueueGpuZoneEnd gpuZoneEnd;
QueueGpuTime gpuTime;
QueueGpuCalibration gpuCalibration;
QueueGpuTimeSync gpuTimeSync;
QueueGpuContextName gpuContextName;
QueueGpuContextNameFat gpuContextNameFat;
QueueMemAlloc memAlloc;
@ -821,6 +830,7 @@ static constexpr size_t QueueDataSize[] = {
sizeof( QueueHeader ), // keep alive
sizeof( QueueHeader ) + sizeof( QueueThreadContext ),
sizeof( QueueHeader ) + sizeof( QueueGpuCalibration ),
sizeof( QueueHeader ) + sizeof( QueueGpuTimeSync ),
sizeof( QueueHeader ), // crash
sizeof( QueueHeader ) + sizeof( QueueCrashReport ),
sizeof( QueueHeader ) + sizeof( QueueZoneValidation ),

View File

@ -172,6 +172,11 @@ struct ___tracy_gpu_calibration_data {
uint8_t context;
};
struct ___tracy_gpu_time_sync_data {
int64_t gpuTime;
uint8_t context;
};
// Some containers don't support storing const types.
// This struct, as visible to user, is immutable, so treat it as if const was declared here.
typedef /*const*/ struct ___tracy_c_zone_context TracyCZoneCtx;
@ -204,6 +209,7 @@ TRACY_API void ___tracy_emit_gpu_time( const struct ___tracy_gpu_time_data );
TRACY_API void ___tracy_emit_gpu_new_context( const struct ___tracy_gpu_new_context_data );
TRACY_API void ___tracy_emit_gpu_context_name( const struct ___tracy_gpu_context_name_data );
TRACY_API void ___tracy_emit_gpu_calibration( const struct ___tracy_gpu_calibration_data );
TRACY_API void ___tracy_emit_gpu_time_sync( const struct ___tracy_gpu_time_sync_data );
TRACY_API void ___tracy_emit_gpu_zone_begin_serial( const struct ___tracy_gpu_zone_begin_data );
TRACY_API void ___tracy_emit_gpu_zone_begin_callstack_serial( const struct ___tracy_gpu_zone_begin_callstack_data );
@ -214,6 +220,7 @@ TRACY_API void ___tracy_emit_gpu_time_serial( const struct ___tracy_gpu_time_dat
TRACY_API void ___tracy_emit_gpu_new_context_serial( const struct ___tracy_gpu_new_context_data );
TRACY_API void ___tracy_emit_gpu_context_name_serial( const struct ___tracy_gpu_context_name_data );
TRACY_API void ___tracy_emit_gpu_calibration_serial( const struct ___tracy_gpu_calibration_data );
TRACY_API void ___tracy_emit_gpu_time_sync_serial( const struct ___tracy_gpu_time_sync_data );
TRACY_API int ___tracy_connected(void);

View File

@ -195,6 +195,9 @@ void EventDebug( const QueueItem& ev )
case QueueType::GpuCalibration:
fprintf( f, "ev %i (GpuCalibration)\n", ev.hdr.idx );
break;
case QueueType::GpuTimeSync:
fprintf( f, "ev %i (GpuTimeSync)\n", ev.hdr.idx );
break;
case QueueType::Crash:
fprintf( f, "ev %i (Crash)\n", ev.hdr.idx );
break;

View File

@ -4589,6 +4589,9 @@ bool Worker::Process( const QueueItem& ev )
case QueueType::GpuCalibration:
ProcessGpuCalibration( ev.gpuCalibration );
break;
case QueueType::GpuTimeSync:
ProcessGpuTimeSync( ev.gpuTimeSync );
break;
case QueueType::GpuContextName:
ProcessGpuContextName( ev.gpuContextName );
break;
@ -5921,6 +5924,29 @@ void Worker::ProcessGpuCalibration( const QueueGpuCalibration& ev )
ctx->calibratedGpuTime = gpuTime;
ctx->calibratedCpuTime = TscTime( ev.cpuTime );
}
void Worker::ProcessGpuTimeSync( const QueueGpuTimeSync& ev )
{
auto ctx = m_gpuCtxMap[ev.context];
assert( ctx );
int64_t gpuTime;
if( ctx->period == 1.f )
{
gpuTime = ev.gpuTime;
}
else
{
gpuTime = int64_t( double( ctx->period ) * ev.gpuTime ); // precision loss
}
const auto cpuTime = TscTime( ev.cpuTime );
ctx->timeDiff = cpuTime - gpuTime;
ctx->lastGpuTime = 0;
ctx->overflow = 0;
ctx->overflowMul = 0;
}
void Worker::ProcessGpuContextName( const QueueGpuContextName& ev )
{

View File

@ -722,6 +722,7 @@ private:
tracy_force_inline void ProcessGpuZoneEnd( const QueueGpuZoneEnd& ev, bool serial );
tracy_force_inline void ProcessGpuTime( const QueueGpuTime& ev );
tracy_force_inline void ProcessGpuCalibration( const QueueGpuCalibration& ev );
tracy_force_inline void ProcessGpuTimeSync( const QueueGpuTimeSync& ev );
tracy_force_inline void ProcessGpuContextName( const QueueGpuContextName& ev );
tracy_force_inline MemEvent* ProcessMemAlloc( const QueueMemAlloc& ev );
tracy_force_inline MemEvent* ProcessMemAllocNamed( const QueueMemAlloc& ev );