mirror of
https://github.com/wolfpld/tracy.git
synced 2025-03-20 07:40:02 +08:00
Migrate drawing GPU data to the new timeline item system.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "TracyMouse.hpp"
|
||||
#include "TracyPrint.hpp"
|
||||
#include "TracySourceView.hpp"
|
||||
#include "TracyTimelineItemGpu.hpp"
|
||||
#include "TracyTimelineItemPlot.hpp"
|
||||
#include "TracyTimelineItemThread.hpp"
|
||||
#include "TracyView.hpp"
|
||||
@@ -339,294 +340,13 @@ void View::DrawTimeline()
|
||||
const auto to = 9.f;
|
||||
const auto th = ( ty - to ) * sqrt( 3 ) * 0.5;
|
||||
|
||||
// gpu zones
|
||||
if( m_vd.drawGpuZones )
|
||||
{
|
||||
for( size_t i=0; i<m_worker.GetGpuData().size(); i++ )
|
||||
for( auto& v : m_worker.GetGpuData() )
|
||||
{
|
||||
const auto& v = m_worker.GetGpuData()[i];
|
||||
auto& vis = m_tc.Vis( v );
|
||||
if( !vis.visible )
|
||||
{
|
||||
vis.height = 0;
|
||||
vis.offset = 0;
|
||||
continue;
|
||||
}
|
||||
bool& showFull = vis.showFull;
|
||||
ImGui::PushID( &vis );
|
||||
|
||||
const auto yPos = m_tc.AdjustThreadPosition( vis, wpos.y, offset );
|
||||
const auto oldOffset = offset;
|
||||
ImGui::PushClipRect( wpos, wpos + ImVec2( w, oldOffset + vis.height ), true );
|
||||
|
||||
const auto singleThread = v->threadData.size() == 1;
|
||||
int depth = 0;
|
||||
offset += ostep;
|
||||
if( showFull && !v->threadData.empty() )
|
||||
{
|
||||
for( auto& td : v->threadData )
|
||||
{
|
||||
auto& tl = td.second.timeline;
|
||||
assert( !tl.empty() );
|
||||
if( tl.is_magic() )
|
||||
{
|
||||
auto& tlm = *(Vector<GpuEvent>*)&tl;
|
||||
if( tlm.front().GpuStart() >= 0 )
|
||||
{
|
||||
const auto begin = tlm.front().GpuStart();
|
||||
const auto drift = GpuDrift( v );
|
||||
if( !singleThread ) offset += sstep;
|
||||
const auto partDepth = DispatchGpuZoneLevel( tl, hover, pxns, int64_t( nspx ), wpos, offset, 0, v->thread, yMin, yMax, begin, drift );
|
||||
if( partDepth != 0 )
|
||||
{
|
||||
if( !singleThread )
|
||||
{
|
||||
ImGui::PushFont( m_smallFont );
|
||||
DrawTextContrast( draw, wpos + ImVec2( ty, offset-1-sstep ), 0xFFFFAAAA, m_worker.GetThreadName( td.first ) );
|
||||
DrawLine( draw, dpos + ImVec2( 0, offset+sty-sstep ), dpos + ImVec2( w, offset+sty-sstep ), 0x22FFAAAA );
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
offset += ostep * partDepth;
|
||||
depth += partDepth;
|
||||
}
|
||||
else if( !singleThread )
|
||||
{
|
||||
offset -= sstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( tl.front()->GpuStart() >= 0 )
|
||||
{
|
||||
const auto begin = tl.front()->GpuStart();
|
||||
const auto drift = GpuDrift( v );
|
||||
if( !singleThread ) offset += sstep;
|
||||
const auto partDepth = DispatchGpuZoneLevel( tl, hover, pxns, int64_t( nspx ), wpos, offset, 0, v->thread, yMin, yMax, begin, drift );
|
||||
if( partDepth != 0 )
|
||||
{
|
||||
if( !singleThread )
|
||||
{
|
||||
ImGui::PushFont( m_smallFont );
|
||||
DrawTextContrast( draw, wpos + ImVec2( ty, offset-1-sstep ), 0xFFFFAAAA, m_worker.GetThreadName( td.first ) );
|
||||
DrawLine( draw, dpos + ImVec2( 0, offset+sty-sstep ), dpos + ImVec2( w, offset+sty-sstep ), 0x22FFAAAA );
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
offset += ostep * partDepth;
|
||||
depth += partDepth;
|
||||
}
|
||||
else if( !singleThread )
|
||||
{
|
||||
offset -= sstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
offset += ostep * 0.2f;
|
||||
|
||||
if( !m_vd.drawEmptyLabels && showFull && depth == 0 )
|
||||
{
|
||||
vis.height = 0;
|
||||
vis.offset = 0;
|
||||
offset = oldOffset;
|
||||
}
|
||||
else if( yPos + ostep >= yMin && yPos <= yMax )
|
||||
{
|
||||
DrawLine( draw, dpos + ImVec2( 0, oldOffset + ostep - 1 ), dpos + ImVec2( w, oldOffset + ostep - 1 ), 0x33FFFFFF );
|
||||
|
||||
if( showFull )
|
||||
{
|
||||
draw->AddTriangleFilled( wpos + ImVec2( to/2, oldOffset + to/2 ), wpos + ImVec2( ty - to/2, oldOffset + to/2 ), wpos + ImVec2( ty * 0.5, oldOffset + to/2 + th ), 0xFFFFAAAA );
|
||||
}
|
||||
else
|
||||
{
|
||||
draw->AddTriangle( wpos + ImVec2( to/2, oldOffset + to/2 ), wpos + ImVec2( to/2, oldOffset + ty - to/2 ), wpos + ImVec2( to/2 + th, oldOffset + ty * 0.5 ), 0xFF886666, 2.0f );
|
||||
}
|
||||
|
||||
const bool isMultithreaded = (v->type == GpuContextType::Vulkan) || (v->type == GpuContextType::OpenCL) || (v->type == GpuContextType::Direct3D12);
|
||||
|
||||
float boxwidth;
|
||||
char buf[64];
|
||||
sprintf( buf, "%s context %zu", GpuContextNames[(int)v->type], i );
|
||||
if( v->name.Active() )
|
||||
{
|
||||
char tmp[4096];
|
||||
sprintf( tmp, "%s: %s", buf, m_worker.GetString( v->name ) );
|
||||
DrawTextContrast( draw, wpos + ImVec2( ty, oldOffset ), showFull ? 0xFFFFAAAA : 0xFF886666, tmp );
|
||||
boxwidth = ImGui::CalcTextSize( tmp ).x;
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTextContrast( draw, wpos + ImVec2( ty, oldOffset ), showFull ? 0xFFFFAAAA : 0xFF886666, buf );
|
||||
boxwidth = ImGui::CalcTextSize( buf ).x;
|
||||
}
|
||||
|
||||
if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( 0, oldOffset ), wpos + ImVec2( ty + boxwidth, oldOffset + ty ) ) )
|
||||
{
|
||||
if( IsMouseClicked( 0 ) )
|
||||
{
|
||||
showFull = !showFull;
|
||||
}
|
||||
if( IsMouseClicked( 2 ) )
|
||||
{
|
||||
int64_t t0 = std::numeric_limits<int64_t>::max();
|
||||
int64_t t1 = std::numeric_limits<int64_t>::min();
|
||||
for( auto& td : v->threadData )
|
||||
{
|
||||
int64_t _t0;
|
||||
if( td.second.timeline.is_magic() )
|
||||
{
|
||||
_t0 = ((Vector<GpuEvent>*)&td.second.timeline)->front().GpuStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
_t0 = td.second.timeline.front()->GpuStart();
|
||||
}
|
||||
if( _t0 >= 0 )
|
||||
{
|
||||
// FIXME
|
||||
t0 = std::min( t0, _t0 );
|
||||
if( td.second.timeline.is_magic() )
|
||||
{
|
||||
t1 = std::max( t1, std::min( m_worker.GetLastTime(), m_worker.GetZoneEnd( ((Vector<GpuEvent>*)&td.second.timeline)->back() ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
t1 = std::max( t1, std::min( m_worker.GetLastTime(), m_worker.GetZoneEnd( *td.second.timeline.back() ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( t0 < t1 )
|
||||
{
|
||||
ZoomToRange( t0, t1 );
|
||||
}
|
||||
}
|
||||
if( IsMouseClicked( 1 ) )
|
||||
{
|
||||
ImGui::OpenPopup( "menuPopup" );
|
||||
}
|
||||
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::TextUnformatted( buf );
|
||||
if( v->name.Active() ) TextFocused( "Name:", m_worker.GetString( v->name ) );
|
||||
ImGui::Separator();
|
||||
if( !isMultithreaded )
|
||||
{
|
||||
SmallColorBox( GetThreadColor( v->thread, 0 ) );
|
||||
ImGui::SameLine();
|
||||
TextFocused( "Thread:", m_worker.GetThreadName( v->thread ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !v->threadData.empty() )
|
||||
{
|
||||
if( v->threadData.size() == 1 )
|
||||
{
|
||||
auto it = v->threadData.begin();
|
||||
auto tid = it->first;
|
||||
if( tid == 0 )
|
||||
{
|
||||
if( !it->second.timeline.empty() )
|
||||
{
|
||||
if( it->second.timeline.is_magic() )
|
||||
{
|
||||
auto& tl = *(Vector<GpuEvent>*)&it->second.timeline;
|
||||
tid = m_worker.DecompressThread( tl.begin()->Thread() );
|
||||
}
|
||||
else
|
||||
{
|
||||
tid = m_worker.DecompressThread( (*it->second.timeline.begin())->Thread() );
|
||||
}
|
||||
}
|
||||
}
|
||||
SmallColorBox( GetThreadColor( tid, 0 ) );
|
||||
ImGui::SameLine();
|
||||
TextFocused( "Thread:", m_worker.GetThreadName( tid ) );
|
||||
ImGui::SameLine();
|
||||
ImGui::TextDisabled( "(%s)", RealToString( tid ) );
|
||||
if( m_worker.IsThreadFiber( tid ) )
|
||||
{
|
||||
ImGui::SameLine();
|
||||
TextColoredUnformatted( ImVec4( 0.2f, 0.6f, 0.2f, 1.f ), "Fiber" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::TextDisabled( "Threads:" );
|
||||
ImGui::Indent();
|
||||
for( auto& td : v->threadData )
|
||||
{
|
||||
SmallColorBox( GetThreadColor( td.first, 0 ) );
|
||||
ImGui::SameLine();
|
||||
ImGui::TextUnformatted( m_worker.GetThreadName( td.first ) );
|
||||
ImGui::SameLine();
|
||||
ImGui::TextDisabled( "(%s)", RealToString( td.first ) );
|
||||
}
|
||||
ImGui::Unindent();
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !v->threadData.empty() )
|
||||
{
|
||||
int64_t t0 = std::numeric_limits<int64_t>::max();
|
||||
for( auto& td : v->threadData )
|
||||
{
|
||||
int64_t _t0;
|
||||
if( td.second.timeline.is_magic() )
|
||||
{
|
||||
_t0 = ((Vector<GpuEvent>*)&td.second.timeline)->front().GpuStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
_t0 = td.second.timeline.front()->GpuStart();
|
||||
}
|
||||
if( _t0 >= 0 )
|
||||
{
|
||||
t0 = std::min( t0, _t0 );
|
||||
}
|
||||
}
|
||||
if( t0 != std::numeric_limits<int64_t>::max() )
|
||||
{
|
||||
TextFocused( "Appeared at", TimeToString( t0 ) );
|
||||
}
|
||||
}
|
||||
TextFocused( "Zone count:", RealToString( v->count ) );
|
||||
if( v->period != 1.f )
|
||||
{
|
||||
TextFocused( "Timestamp accuracy:", TimeToString( v->period ) );
|
||||
}
|
||||
if( v->overflow != 0 )
|
||||
{
|
||||
ImGui::Separator();
|
||||
ImGui::TextUnformatted( "GPU timer overflow has been detected." );
|
||||
TextFocused( "Timer resolution:", RealToString( 63 - TracyLzcnt( v->overflow ) ) );
|
||||
ImGui::SameLine();
|
||||
TextDisabledUnformatted( "bits" );
|
||||
}
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
if( ImGui::BeginPopup( "menuPopup" ) )
|
||||
{
|
||||
if( ImGui::MenuItem( ICON_FA_EYE_SLASH " Hide" ) )
|
||||
{
|
||||
vis.visible = false;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
m_tc.AdjustThreadHeight( vis, oldOffset, offset );
|
||||
ImGui::PopClipRect();
|
||||
ImGui::PopID();
|
||||
m_tc.AddItem<TimelineItemGpu>( v );
|
||||
}
|
||||
}
|
||||
|
||||
// zones
|
||||
if( m_vd.drawCpuData && m_worker.HasContextSwitches() )
|
||||
{
|
||||
offset = DrawCpuData( offset, pxns, wpos, hover, yMin, yMax );
|
||||
|
||||
Reference in New Issue
Block a user