diff --git a/profiler/src/profiler/TracyView_ZoneInfo.cpp b/profiler/src/profiler/TracyView_ZoneInfo.cpp index 60deca0d..0a6526d6 100644 --- a/profiler/src/profiler/TracyView_ZoneInfo.cpp +++ b/profiler/src/profiler/TracyView_ZoneInfo.cpp @@ -28,6 +28,80 @@ inline uint32_t GetZoneCallstack( const GpuEvent& ev, const Worker& wo return ev.callstack.Val(); } +static void SortChildIndices( uint32_t* cti, size_t count, const uint64_t* ctt, const Vector* ctn, const ImGuiTableColumnSortSpecs& sortspec ) +{ + const bool asc = sortspec.SortDirection == ImGuiSortDirection_Ascending; + if( sortspec.ColumnIndex == 0 ) + { + const Vector& names = *ctn; + if( asc ) + { + pdqsort_branchless( cti, cti + count, [&names, ctt]( const auto& lhs, const auto& rhs ) { + const int cmp = strcmp( names[lhs], names[rhs] ); + if( cmp != 0 ) return cmp < 0; + return ctt[lhs] > ctt[rhs]; + } ); + } + else + { + pdqsort_branchless( cti, cti + count, [&names, ctt]( const auto& lhs, const auto& rhs ) { + const int cmp = strcmp( names[lhs], names[rhs] ); + if( cmp != 0 ) return cmp > 0; + return ctt[lhs] > ctt[rhs]; + } ); + } + } + else if( asc ) + { + pdqsort_branchless( cti, cti + count, [ctt]( const auto& lhs, const auto& rhs ) { return ctt[lhs] < ctt[rhs]; } ); + } + else + { + pdqsort_branchless( cti, cti + count, [ctt]( const auto& lhs, const auto& rhs ) { return ctt[lhs] > ctt[rhs]; } ); + } +} + +struct ChildGroup +{ + int16_t srcloc; + uint64_t t; + Vector v; + const char* name; +}; + +static void SortChildGroups( Vector& cgvec, const ImGuiTableColumnSortSpecs& sortspec, const Worker& worker ) +{ + const bool asc = sortspec.SortDirection == ImGuiSortDirection_Ascending; + if( sortspec.ColumnIndex == 0 ) + { + for( auto& it : cgvec ) it->name = worker.GetZoneName( worker.GetSourceLocation( it->srcloc ) ); + if( asc ) + { + pdqsort_branchless( cgvec.begin(), cgvec.end(), []( const auto& lhs, const auto& rhs ) { + const int cmp = strcmp( lhs->name, rhs->name ); + if( cmp != 0 ) return cmp < 0; + return lhs->t > rhs->t; + } ); + } + else + { + pdqsort_branchless( cgvec.begin(), cgvec.end(), []( const auto& lhs, const auto& rhs ) { + const int cmp = strcmp( lhs->name, rhs->name ); + if( cmp != 0 ) return cmp > 0; + return lhs->t > rhs->t; + } ); + } + } + else if( asc ) + { + pdqsort_branchless( cgvec.begin(), cgvec.end(), []( const auto& lhs, const auto& rhs ) { return lhs->t < rhs->t; } ); + } + else + { + pdqsort_branchless( cgvec.begin(), cgvec.end(), []( const auto& lhs, const auto& rhs ) { return lhs->t > rhs->t; } ); + } +} + void View::CalcZoneTimeData( unordered_flat_map& data, int64_t& ztime, const ZoneEvent& zone ) { assert( zone.HasChildren() ); @@ -1145,12 +1219,6 @@ void View::DrawZoneInfoChildren( const V& children, int64_t ztime ) if( m_groupChildrenLocations ) { - struct ChildGroup - { - int16_t srcloc; - uint64_t t; - Vector v; - }; uint64_t ctime = 0; unordered_flat_map cmap; cmap.reserve( 128 ); @@ -1178,23 +1246,30 @@ void View::DrawZoneInfoChildren( const V& children, int64_t ztime ) cgvec[idx++] = &it.second; } - pdqsort_branchless( cgvec.begin(), cgvec.end(), []( const auto& lhs, const auto& rhs ) { return lhs->t > rhs->t; } ); + if( !ImGui::BeginTable( "##childzones", 2, ImGuiTableFlags_Sortable | ImGuiTableFlags_BordersInnerV ) ) return; + ImGui::TableSetupColumn( "Zone" ); + ImGui::TableSetupColumn( "Time", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_PreferSortDescending ); + ImGui::TableHeadersRow(); - ImGui::Columns( 2 ); - ImGui::Indent( ImGui::GetTreeNodeToLabelSpacing() * 2 ); + const auto& sortspec = *ImGui::TableGetSortSpecs()->Specs; + SortChildGroups( cgvec, sortspec, m_worker ); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); TextColoredUnformatted( ImVec4( 1.0f, 1.0f, 0.4f, 1.0f ), "Self time" ); - ImGui::Unindent( ImGui::GetTreeNodeToLabelSpacing() * 2 ); - ImGui::NextColumn(); + ImGui::TableNextColumn(); char buf[128]; PrintStringPercent( buf, TimeToString( ztime - ctime ), double( ztime - ctime ) / ztime * 100 ); ImGui::ProgressBar( double( ztime - ctime ) * rztime, ImVec2( -1, ty ), buf ); - ImGui::NextColumn(); + for( size_t i=0; i( new uint64_t[cgr.v.size()] ); @@ -1259,7 +1333,13 @@ void View::DrawZoneInfoChildren( const V& children, int64_t ztime ) cti[i] = uint32_t( i ); } - pdqsort_branchless( cti.get(), cti.get() + cgr.v.size(), [&ctt] ( const auto& lhs, const auto& rhs ) { return ctt[lhs] > ctt[rhs]; } ); + Vector ctn; + if( sortspec.ColumnIndex == 0 ) + { + ctn.reserve_and_use( cgr.v.size() ); + for( size_t i=0; i ctt[rhs]; } ); + if( !ImGui::BeginTable( "##childzones", 2, ImGuiTableFlags_Sortable | ImGuiTableFlags_BordersInnerV ) ) return; + ImGui::TableSetupColumn( "Zone" ); + ImGui::TableSetupColumn( "Time", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_PreferSortDescending ); + ImGui::TableHeadersRow(); - ImGui::Columns( 2 ); - ImGui::Indent( ImGui::GetTreeNodeToLabelSpacing() ); + const auto& sortspec = *ImGui::TableGetSortSpecs()->Specs; + Vector ctn; + if( sortspec.ColumnIndex == 0 ) + { + ctn.reserve_and_use( children.size() ); + for( size_t i=0; i v; - }; uint64_t ctime = 0; unordered_flat_map cmap; cmap.reserve( 128 ); @@ -1661,23 +1748,30 @@ void View::DrawGpuInfoChildren( const V& children, int64_t ztime ) cgvec[idx++] = &it.second; } - pdqsort_branchless( cgvec.begin(), cgvec.end(), []( const auto& lhs, const auto& rhs ) { return lhs->t > rhs->t; } ); + if( !ImGui::BeginTable( "##childzones", 2, ImGuiTableFlags_Sortable | ImGuiTableFlags_BordersInnerV ) ) return; + ImGui::TableSetupColumn( "Zone" ); + ImGui::TableSetupColumn( "Time", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_PreferSortDescending ); + ImGui::TableHeadersRow(); - ImGui::Columns( 2 ); - ImGui::Indent( ImGui::GetTreeNodeToLabelSpacing() ); + const auto& sortspec = *ImGui::TableGetSortSpecs()->Specs; + SortChildGroups( cgvec, sortspec, m_worker ); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); TextColoredUnformatted( ImVec4( 1.0f, 1.0f, 0.4f, 1.0f ), "Self time" ); - ImGui::Unindent( ImGui::GetTreeNodeToLabelSpacing() ); - ImGui::NextColumn(); + ImGui::TableNextColumn(); char buf[128]; PrintStringPercent( buf, TimeToString( ztime - ctime ), double( ztime - ctime ) / ztime * 100 ); ImGui::ProgressBar( double( ztime - ctime ) * rztime, ImVec2( -1, ty ), buf ); - ImGui::NextColumn(); + for( size_t i=0; i( new uint64_t[cgr.v.size()] ); @@ -1738,41 +1831,53 @@ void View::DrawGpuInfoChildren( const V& children, int64_t ztime ) cti[i] = uint32_t( i ); } - pdqsort_branchless( cti.get(), cti.get() + cgr.v.size(), [&ctt] ( const auto& lhs, const auto& rhs ) { return ctt[lhs] > ctt[rhs]; } ); - - for( size_t i=0; i ctn; + if( sortspec.ColumnIndex == 0 ) { - auto& cev = a(children[cgr.v[cti[i]]]); - const auto txt = m_worker.GetZoneName( cev ); - bool b = false; - ImGui::Indent(); - ImGui::PushID( (int)cgr.v[cti[i]] ); - if( ImGui::Selectable( txt, &b, ImGuiSelectableFlags_SpanAllColumns ) ) + ctn.reserve_and_use( cgr.v.size() ); + for( size_t i=0; i ctt[rhs]; } ); + if( !ImGui::BeginTable( "##childzones", 2, ImGuiTableFlags_Sortable | ImGuiTableFlags_BordersInnerV ) ) return; + ImGui::TableSetupColumn( "Zone" ); + ImGui::TableSetupColumn( "Time", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_PreferSortDescending ); + ImGui::TableHeadersRow(); - ImGui::Columns( 2 ); + const auto& sortspec = *ImGui::TableGetSortSpecs()->Specs; + Vector ctn; + if( sortspec.ColumnIndex == 0 ) + { + ctn.reserve_and_use( children.size() ); + for( size_t i=0; i