diff --git a/server/TracyEvent.hpp b/server/TracyEvent.hpp index dbb2fcf5..6daecc76 100644 --- a/server/TracyEvent.hpp +++ b/server/TracyEvent.hpp @@ -137,7 +137,7 @@ struct GpuEvent // All above is read/saved as-is. uint16_t thread; - Vector child; + int32_t child; }; enum { GpuEventSize = sizeof( GpuEvent ) }; diff --git a/server/TracyView.cpp b/server/TracyView.cpp index a796d6fb..2f8adcba 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -1624,9 +1624,9 @@ int View::DrawGpuZoneLevel( const Vector& vec, bool hover, double pxn } else { - if( !ev.child.empty() ) + if( ev.child >= 0 ) { - const auto d = DispatchGpuZoneLevel( ev.child, hover, pxns, wpos, _offset, depth, thread, yMin, yMax, begin, drift ); + const auto d = DispatchGpuZoneLevel( m_worker.GetGpuChildren( ev.child ), hover, pxns, wpos, _offset, depth, thread, yMin, yMax, begin, drift ); if( d > maxdepth ) maxdepth = d; } @@ -1740,9 +1740,9 @@ int View::SkipGpuZoneLevel( const Vector& vec, bool hover, double pxn } else { - if( !ev.child.empty() ) + if( ev.child >= 0 ) { - const auto d = DispatchGpuZoneLevel( ev.child, hover, pxns, wpos, _offset, depth, thread, yMin, yMax, begin, drift ); + const auto d = DispatchGpuZoneLevel( m_worker.GetGpuChildren( ev.child ), hover, pxns, wpos, _offset, depth, thread, yMin, yMax, begin, drift ); if( d > maxdepth ) maxdepth = d; } ++it; @@ -3378,26 +3378,27 @@ void View::DrawGpuInfoWindow() } } ); - if( !ev.child.empty() ) + if( ev.child >= 0 ) { + const auto& children = m_worker.GetGpuChildren( ev.child ); bool expand = ImGui::TreeNode( "Child zones" ); ImGui::SameLine(); - ImGui::TextDisabled( "(%s)", RealToString( ev.child.size(), true ) ); + ImGui::TextDisabled( "(%s)", RealToString( children.size(), true ) ); if( expand ) { - auto ctt = std::make_unique( ev.child.size() ); - auto cti = std::make_unique( ev.child.size() ); + auto ctt = std::make_unique( children.size() ); + auto cti = std::make_unique( children.size() ); uint64_t ctime = 0; - for( size_t i=0; igpuStart; + const auto cend = m_worker.GetZoneEnd( *children[i] ); + const auto ct = cend - children[i]->gpuStart; ctime += ct; ctt[i] = ct; cti[i] = uint32_t( i ); } - pdqsort_branchless( cti.get(), cti.get() + ev.child.size(), [&ctt] ( const auto& lhs, const auto& rhs ) { return ctt[lhs] > ctt[rhs]; } ); + pdqsort_branchless( cti.get(), cti.get() + children.size(), [&ctt] ( const auto& lhs, const auto& rhs ) { return ctt[lhs] > ctt[rhs]; } ); const auto ty = ImGui::GetTextLineHeight(); ImGui::Columns( 2 ); @@ -3407,9 +3408,9 @@ void View::DrawGpuInfoWindow() sprintf( buf, "%s (%.2f%%)", TimeToString( ztime - ctime ), double( ztime - ctime ) / ztime * 100 ); ImGui::ProgressBar( double( ztime - ctime ) / ztime, ImVec2( -1, ty ), buf ); ImGui::NextColumn(); - for( size_t i=0; ibegin() ) --it; if( zone.gpuEnd >= 0 && (*it)->gpuStart > zone.gpuEnd ) break; if( *it == &zone ) return parent; - if( (*it)->child.empty() ) break; + if( (*it)->child < 0 ) break; parent = *it; - timeline = &parent->child; + timeline = &m_worker.GetGpuChildren( parent->child ); } } return nullptr; @@ -6270,8 +6271,8 @@ uint64_t View::GetZoneThread( const GpuEvent& zone ) const if( it != timeline->begin() ) --it; if( zone.gpuEnd >= 0 && (*it)->gpuStart > zone.gpuEnd ) break; if( *it == &zone ) return ctx->thread; - if( (*it)->child.empty() ) break; - timeline = &(*it)->child; + if( (*it)->child < 0 ) break; + timeline = &m_worker.GetGpuChildren( (*it)->child ); } } return 0; @@ -6294,8 +6295,8 @@ const GpuCtxData* View::GetZoneCtx( const GpuEvent& zone ) const if( it != timeline->begin() ) --it; if( zone.gpuEnd >= 0 && (*it)->gpuStart > zone.gpuEnd ) break; if( *it == &zone ) return ctx; - if( (*it)->child.empty() ) break; - timeline = &(*it)->child; + if( (*it)->child < 0 ) break; + timeline = &m_worker.GetGpuChildren( (*it)->child ); } } return nullptr; diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index 31b7a53b..e5fd5b16 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -526,12 +526,16 @@ Worker::Worker( FileRead& f, EventType::Type eventMask ) if( fileVer <= FileVersion( 0, 3, 1 ) ) { ctx->period = 1.f; - ReadTimelinePre032( f, ctx->timeline ); + uint64_t tsz; + f.Read( tsz ); + ReadTimelinePre032( f, ctx->timeline, tsz ); } else { f.Read( ctx->period ); - ReadTimeline( f, ctx->timeline ); + uint64_t tsz; + f.Read( tsz ); + ReadTimeline( f, ctx->timeline, tsz ); } m_data.gpuData.push_back_no_space_check( ctx ); } @@ -687,16 +691,6 @@ finishLoading: } } -template -static inline void ZoneCleanup( Vector& vec ) -{ - for( auto& v : vec ) - { - ZoneCleanup( v->child ); - } - vec.~Vector(); -} - Worker::~Worker() { Shutdown(); @@ -712,10 +706,6 @@ Worker::~Worker() { v->messages.~Vector(); } - for( auto& v : m_data.gpuData ) - { - ZoneCleanup( v->timeline ); - } for( auto& v : m_data.plots ) { v->~PlotData(); @@ -795,8 +785,8 @@ int64_t Worker::GetZoneEnd( const GpuEvent& ev ) for(;;) { if( ptr->gpuEnd >= 0 ) return ptr->gpuEnd; - if( ptr->child.empty() ) return ptr->gpuStart; - ptr = ptr->child.back(); + if( ptr->child < 0 ) return ptr->gpuStart; + ptr = GetGpuChildren( ptr->child ).back(); } } @@ -2084,7 +2074,13 @@ void Worker::ProcessGpuZoneBeginImpl( GpuEvent* zone, const QueueGpuZoneBegin& e auto timeline = &ctx->timeline; if( !ctx->stack.empty() ) { - timeline = &ctx->stack.back()->child; + auto back = ctx->stack.back(); + if( back->child < 0 ) + { + back->child = int32_t( m_data.m_gpuChildren.size() ); + m_data.m_gpuChildren.push_back( Vector() ); + } + timeline = &m_data.m_gpuChildren[back->child]; } timeline->push_back( zone ); @@ -2485,23 +2481,39 @@ void Worker::ReadTimelinePre033( FileRead& f, ZoneEvent* zone, uint16_t thread, } } -void Worker::ReadTimeline( FileRead& f, Vector& vec ) +void Worker::ReadTimeline( FileRead& f, GpuEvent* zone ) { uint64_t sz; f.Read( sz ); - if( sz != 0 ) + if( sz == 0 ) { - ReadTimeline( f, vec, sz ); + zone->child = -1; + } + else + { + zone->child = m_data.m_gpuChildren.size(); + m_data.m_gpuChildren.push_back( Vector() ); + Vector tmp; + ReadTimeline( f, tmp, sz ); + m_data.m_gpuChildren[zone->child] = std::move( tmp ); } } -void Worker::ReadTimelinePre032( FileRead& f, Vector& vec ) +void Worker::ReadTimelinePre032( FileRead& f, GpuEvent* zone ) { uint64_t sz; f.Read( sz ); - if( sz != 0 ) + if( sz == 0 ) { - ReadTimelinePre032( f, vec, sz ); + zone->child = -1; + } + else + { + zone->child = m_data.m_gpuChildren.size(); + m_data.m_gpuChildren.push_back( Vector() ); + Vector tmp; + ReadTimelinePre032( f, tmp, sz ); + m_data.m_gpuChildren[zone->child] = std::move( tmp ); } } @@ -2594,7 +2606,7 @@ void Worker::ReadTimeline( FileRead& f, Vector& vec, uint64_t size ) uint64_t thread; f.Read( thread ); zone->thread = CompressThread( thread ); - ReadTimeline( f, zone->child ); + ReadTimeline( f, zone ); } } @@ -2611,7 +2623,7 @@ void Worker::ReadTimelinePre032( FileRead& f, Vector& vec, uint64_t s f.Read( zone, 36 ); zone->thread = 0; zone->callstack = 0; - ReadTimelinePre032( f, zone->child ); + ReadTimelinePre032( f, zone ); } } @@ -2819,7 +2831,15 @@ void Worker::WriteTimeline( FileWrite& f, const Vector& vec ) f.Write( v, sizeof( GpuEvent::cpuStart ) + sizeof( GpuEvent::cpuEnd ) + sizeof( GpuEvent::gpuStart ) + sizeof( GpuEvent::gpuEnd ) + sizeof( GpuEvent::srcloc ) + sizeof( GpuEvent::callstack ) ); uint64_t thread = DecompressThread( v->thread ); f.Write( &thread, sizeof( thread ) ); - WriteTimeline( f, v->child ); + if( v->child < 0 ) + { + sz = 0; + f.Write( &sz, sizeof( sz ) ); + } + else + { + WriteTimeline( f, GetGpuChildren( v->child ) ); + } } } diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index 10aec31c..c16704e5 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -113,6 +113,7 @@ private: std::pair threadLast; std::vector> m_zoneChildren; + std::vector> m_gpuChildren; }; struct MbpsBlock @@ -176,7 +177,7 @@ public: // before its children have ended). // GetZoneEndDirect() will only return zone's direct timing data, without looking at children. int64_t GetZoneEnd( const ZoneEvent& ev ); - static int64_t GetZoneEnd( const GpuEvent& ev ); + int64_t GetZoneEnd( const GpuEvent& ev ); static tracy_force_inline int64_t GetZoneEndDirect( const ZoneEvent& ev ) { return ev.end >= 0 ? ev.end : ev.start; } static tracy_force_inline int64_t GetZoneEndDirect( const GpuEvent& ev ) { return ev.gpuEnd >= 0 ? ev.gpuEnd : ev.gpuStart; } @@ -192,6 +193,7 @@ public: const char* GetZoneName( const GpuEvent& ev, const SourceLocation& srcloc ) const; tracy_force_inline const Vector& GetZoneChildren( int32_t idx ) const { return m_data.m_zoneChildren[idx]; } + tracy_force_inline const Vector& GetGpuChildren( int32_t idx ) const { return m_data.m_gpuChildren[idx]; } std::vector GetMatchingSourceLocation( const char* query ) const; @@ -300,8 +302,8 @@ private: tracy_force_inline void ReadTimeline( FileRead& f, ZoneEvent* zone, uint16_t thread ); tracy_force_inline void ReadTimelinePre033( FileRead& f, ZoneEvent* zone, uint16_t thread, int fileVer ); - tracy_force_inline void ReadTimeline( FileRead& f, Vector& vec ); - tracy_force_inline void ReadTimelinePre032( FileRead& f, Vector& vec ); + tracy_force_inline void ReadTimeline( FileRead& f, GpuEvent* zone ); + tracy_force_inline void ReadTimelinePre032( FileRead& f, GpuEvent* zone ); tracy_force_inline void ReadTimelineUpdateStatistics( ZoneEvent* zone, uint16_t thread );