diff --git a/TracyOpenGL.hpp b/TracyOpenGL.hpp index 94f20430..c5073640 100644 --- a/TracyOpenGL.hpp +++ b/TracyOpenGL.hpp @@ -5,6 +5,7 @@ #include +#include "Tracy.hpp" #include "client/TracyProfiler.hpp" #define TracyGpuZone( ctx, name ) static const tracy::SourceLocation __tracy_gpu_source_location { __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; auto ___tracy_gpu_zone = tracy::detail::__GpuHelper( ctx, name, &__tracy_gpu_source_location ); @@ -95,6 +96,48 @@ public: tail.store( magic + 1, std::memory_order_release ); } + void Collect() + { + ZoneScopedC( 0x881111 ); + + auto start = m_tail; + auto end = m_head + Num; + auto cnt = ( end - start ) % Num; + while( cnt > 1 ) + { + auto mid = start + cnt / 2; + GLint available; + glGetQueryObjectiv( m_query[mid % Num], GL_QUERY_RESULT_AVAILABLE, &available ); + if( available ) + { + start = mid; + } + else + { + end = mid; + } + cnt = ( end - start ) % Num; + } + + start %= Num; + + while( m_tail != start ) + { + uint64_t time; + glGetQueryObjectui64v( m_query[m_tail], GL_QUERY_RESULT, &time ); + + Magic magic; + auto& token = s_token.ptr; + auto& tail = token->get_tail_index(); + auto item = token->enqueue_begin( magic ); + item->hdr.type = QueueType::GpuTime; + item->gpuTime.gpuTime = (int64_t)time; + item->gpuTime.context = m_context; + tail.store( magic + 1, std::memory_order_release ); + m_tail = ( m_tail + 1 ) % Num; + } + } + private: tracy_force_inline __GpuCtxScope SpawnZone( const char* name, const SourceLocation* srcloc ) { diff --git a/common/TracyQueue.hpp b/common/TracyQueue.hpp index e272d3e0..bfc7f4e8 100644 --- a/common/TracyQueue.hpp +++ b/common/TracyQueue.hpp @@ -32,6 +32,7 @@ enum class QueueType : uint8_t GpuNewContext, GpuZoneBegin, GpuZoneEnd, + GpuTime, NUM_TYPES }; @@ -163,6 +164,12 @@ struct QueueGpuZoneEnd uint16_t context; }; +struct QueueGpuTime +{ + int64_t gpuTime; + uint16_t context; +}; + struct QueueHeader { union @@ -193,6 +200,7 @@ struct QueueItem QueueGpuNewContext gpuNewContext; QueueGpuZoneBegin gpuZoneBegin; QueueGpuZoneEnd gpuZoneEnd; + QueueGpuTime gpuTime; }; }; @@ -225,6 +233,7 @@ static const size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueueGpuNewContext ), sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), sizeof( QueueHeader ) + sizeof( QueueGpuZoneEnd ), + sizeof( QueueHeader ) + sizeof( QueueGpuTime ), }; static_assert( QueueItemSize == 32, "Queue item size not 32 bytes" ); diff --git a/server/TracyView.cpp b/server/TracyView.cpp index f5d8ffda..33f87bac 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -597,6 +597,9 @@ void View::Process( const QueueItem& ev ) case QueueType::GpuZoneEnd: ProcessGpuZoneEnd( ev.gpuZoneEnd ); break; + case QueueType::GpuTime: + ProcessGpuTime( ev.gpuTime ); + break; case QueueType::Terminate: m_terminate = true; break; @@ -908,6 +911,26 @@ void View::ProcessGpuZoneEnd( const QueueGpuZoneEnd& ev ) zone->thread = ev.thread; } +void View::ProcessGpuTime( const QueueGpuTime& ev ) +{ + assert( m_gpuData.size() >= ev.context ); + auto ctx = m_gpuData[ev.context]; + + auto zone = ctx->queue.front(); + if( zone->gpuStart == std::numeric_limits::max() ) + { + std::lock_guard lock( m_lock ); + zone->gpuStart = ctx->timeDiff + ev.gpuTime; + } + else + { + std::lock_guard lock( m_lock ); + zone->gpuEnd = ctx->timeDiff + ev.gpuTime; + } + + ctx->queue.erase( ctx->queue.begin() ); +} + void View::CheckString( uint64_t ptr ) { if( m_strings.find( ptr ) != m_strings.end() ) return; diff --git a/server/TracyView.hpp b/server/TracyView.hpp index 14d161c9..77d2c09e 100644 --- a/server/TracyView.hpp +++ b/server/TracyView.hpp @@ -70,6 +70,7 @@ private: void ProcessGpuNewContext( const QueueGpuNewContext& ev ); void ProcessGpuZoneBegin( const QueueGpuZoneBegin& ev ); void ProcessGpuZoneEnd( const QueueGpuZoneEnd& ev ); + void ProcessGpuTime( const QueueGpuTime& ev ); void CheckString( uint64_t ptr ); void CheckThreadString( uint64_t id );