Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use high-precision vblank timings, if available #33

Merged
merged 4 commits into from
Sep 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/gpuvis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,11 +300,15 @@ void Opts::init()

init_opt_bool( i, desc.c_str(), inikey.c_str(), true );
}

init_opt_bool( OPT_VBlankHighPrecTimestamps, "Use high-precision HW vblank timestamps (if available)", "vblank_high_prec_timestamps", false );

init_opt_bool( OPT_RenderFrameMarkers, "Show render frame markers", "render_framemarkers", true );

// Set up action mappings so we can display hotkeys in render_imgui_opt().
m_options[ OPT_RenderCrtc0 ].action = action_toggle_vblank0;
m_options[ OPT_RenderCrtc1 ].action = action_toggle_vblank1;
m_options[ OPT_VBlankHighPrecTimestamps].action = action_toggle_vblank_hardware_timestamps;
m_options[ OPT_RenderFrameMarkers ].action = action_toggle_framemarkers;

add_opt_graph_rowsize( "gfx", 8 );
Expand Down Expand Up @@ -1937,7 +1941,7 @@ void TraceEvents::init_new_event_vblank( trace_event_t &event )
trace_event_t &event_vblank_queued = m_events[ *vblank_queued_id ];

// If so, set the vblank queued time
event_vblank_queued.duration = event.ts - event_vblank_queued.ts;
event_vblank_queued.duration = event.get_vblank_ts( s_opts().getb( OPT_VBlankHighPrecTimestamps ) ) - event_vblank_queued.ts;
}

m_tdopexpr_locs.add_location_str( "$name=drm_vblank_event", event.id );
Expand All @@ -1947,7 +1951,7 @@ void TraceEvents::init_new_event_vblank( trace_event_t &event )
*/
if ( m_vblank_info[ event.crtc ].last_vblank_ts )
{
int64_t diff = event.ts - m_vblank_info[ event.crtc ].last_vblank_ts;
int64_t diff = event.get_vblank_ts( s_opts().getb( OPT_VBlankHighPrecTimestamps ) ) - m_vblank_info[ event.crtc ].last_vblank_ts;

// Normalize ts diff to known frequencies
diff = normalize_vblank_diff( diff );
Expand All @@ -1957,7 +1961,7 @@ void TraceEvents::init_new_event_vblank( trace_event_t &event )
m_vblank_info[ event.crtc ].count++;
}

m_vblank_info[ event.crtc ].last_vblank_ts = event.ts;
m_vblank_info[ event.crtc ].last_vblank_ts = event.get_vblank_ts( s_opts().getb( OPT_VBlankHighPrecTimestamps ) );
}

// new_event_cb adds all events to array, this function initializes them.
Expand Down Expand Up @@ -4605,6 +4609,8 @@ void MainApp::handle_hotkeys()
s_opts().setb( OPT_RenderCrtc0, !s_opts().getb( OPT_RenderCrtc0 ) );
if ( s_actions().get( action_toggle_vblank1 ) )
s_opts().setb( OPT_RenderCrtc1, !s_opts().getb( OPT_RenderCrtc1 ) );
if ( s_actions().get( action_toggle_vblank_hardware_timestamps ) )
s_opts().setb( OPT_VBlankHighPrecTimestamps, !s_opts().getb( OPT_VBlankHighPrecTimestamps ) );
if ( s_actions().get( action_toggle_framemarkers ) )
s_opts().setb( OPT_RenderFrameMarkers, !s_opts().getb( OPT_RenderFrameMarkers ) );

Expand Down
1 change: 1 addition & 0 deletions src/gpuvis.h
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,7 @@ enum : uint32_t
OPT_RenderCrtc7,
OPT_RenderCrtc8,
OPT_RenderCrtc9,
OPT_VBlankHighPrecTimestamps,
OPT_RenderFrameMarkers,
OPT_GraphHeight,
OPT_GraphHeightZoomed,
Expand Down
14 changes: 7 additions & 7 deletions src/gpuvis_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2548,7 +2548,7 @@ static float get_vblank_xdiffs( TraceWin &win, graph_info_t &gi, const std::vect

if ( s_opts().getcrtc( event.crtc ) )
{
float x = gi.ts_to_screenx( event.ts );
float x = gi.ts_to_screenx( event.get_vblank_ts( s_opts().getb( OPT_VBlankHighPrecTimestamps ) ) );

if ( xlast )
xdiff = std::max< float >( xdiff, x - xlast );
Expand Down Expand Up @@ -2595,7 +2595,7 @@ void TraceWin::graph_render_vblanks( graph_info_t &gi )
{
// Handle drm_vblank_event0 .. drm_vblank_event2
uint32_t col = Clamp< uint32_t >( col_VBlank0 + event.crtc, col_VBlank0, col_VBlank2 );
float x = gi.ts_to_screenx( event.ts );
float x = gi.ts_to_screenx( event.get_vblank_ts( s_opts().getb( OPT_VBlankHighPrecTimestamps ) ) );

imgui_drawrect_filled( x, gi.rc.y, imgui_scale( 1.0f ), gi.rc.h,
s_clrs().get( col, alpha ) );
Expand Down Expand Up @@ -4077,13 +4077,13 @@ void TraceWin::graph_mouse_tooltip_vblanks( std::string &ttip, graph_info_t &gi,
{
if ( event.ts < mouse_ts )
{
if ( mouse_ts - event.ts < prev_vblank_ts )
prev_vblank_ts = mouse_ts - event.ts;
if ( mouse_ts - event.get_vblank_ts( s_opts().getb( OPT_VBlankHighPrecTimestamps ) ) < prev_vblank_ts )
prev_vblank_ts = mouse_ts - event.get_vblank_ts( s_opts().getb( OPT_VBlankHighPrecTimestamps ) );
}
if ( event.ts > mouse_ts )
if ( event.get_vblank_ts( s_opts().getb( OPT_VBlankHighPrecTimestamps ) ) > mouse_ts )
{
if ( event.ts - mouse_ts < next_vblank_ts )
next_vblank_ts = event.ts - mouse_ts;
if ( event.get_vblank_ts( s_opts().getb( OPT_VBlankHighPrecTimestamps ) ) - mouse_ts < next_vblank_ts )
next_vblank_ts = event.get_vblank_ts( s_opts().getb( OPT_VBlankHighPrecTimestamps ) ) - mouse_ts;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/gpuvis_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1449,6 +1449,7 @@ void Actions::init()

m_actionmap.push_back( { action_toggle_vblank0, KMOD_CTRL | KMOD_SHIFT, SDLK_m, "Graph: Toggle showing vblank 0 markers" } );
m_actionmap.push_back( { action_toggle_vblank1, KMOD_CTRL | KMOD_SHIFT, SDLK_n, "Graph: Toggle showing vblank 1 markers" } );
m_actionmap.push_back( { action_toggle_vblank_hardware_timestamps, KMOD_CTRL | KMOD_SHIFT, SDLK_k, "Graph: Toggle showing hardware vblank timestamps" } );
m_actionmap.push_back( { action_toggle_framemarkers, KMOD_CTRL | KMOD_SHIFT, SDLK_f, "Graph: Toggle showing Frame Markers" } );
m_actionmap.push_back( { action_toggle_frame_filters, KMOD_CTRL | KMOD_SHIFT, SDLK_r, "Graph: Toggle Frame Filters" } );

Expand Down
1 change: 1 addition & 0 deletions src/gpuvis_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ enum action_t

action_toggle_vblank0,
action_toggle_vblank1,
action_toggle_vblank_hardware_timestamps,
action_toggle_framemarkers,
action_toggle_frame_filters,

Expand Down
28 changes: 28 additions & 0 deletions src/trace-cmd/trace-read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1582,6 +1582,8 @@ class trace_data_t
ftrace_function_str = strpool.getstr( "ftrace-function" );
drm_vblank_event_str = strpool.getstr( "drm_vblank_event" );
sched_switch_str = strpool.getstr( "sched_switch" );
time_str = strpool.getstr( "time" );
high_prec_str = strpool.getstr( "high_prec" );
}

public:
Expand All @@ -1600,6 +1602,8 @@ class trace_data_t
const char *ftrace_function_str;
const char *drm_vblank_event_str;
const char *sched_switch_str;
const char *time_str;
const char *high_prec_str;
};

static void init_event_flags( trace_data_t &trace_data, trace_event_t &event )
Expand Down Expand Up @@ -1734,6 +1738,30 @@ static int trace_enum_events( trace_data_t &trace_data, tracecmd_input_t *handle

trace_event.crtc = val;
}
else if ( trace_event.name == trace_data.drm_vblank_event_str &&
format_name == trace_data.time_str &&
!strcmp(handle->pevent->trace_clock, "mono"))
{
// for drm_vblank_event, if "time" field is available,
// and the trace-clock is monotonic, store the timestamp
// passed along with the vblank event
unsigned long long val = pevent_read_number( pevent,
( char * )record->data + format->offset, format->size );

trace_event.vblank_ts = val - trace_data.trace_info.min_file_ts;
}
else if ( trace_event.name == trace_data.drm_vblank_event_str &&
format_name == trace_data.high_prec_str &&
!strcmp(handle->pevent->trace_clock, "mono"))
{
// for drm_vblank_event, if "high_prec" field is available,
// and the trace-lock is monotonic, store the field whether or not
// the passed timestamp is actually from a high-precision source
unsigned long long val = pevent_read_number( pevent,
( char * )record->data + format->offset, format->size );

trace_event.vblank_ts_high_prec = val != 0;
}
else if ( is_ftrace_function )
{
bool is_ip = ( format_name == trace_data.ip_str );
Expand Down
35 changes: 19 additions & 16 deletions src/trace-cmd/trace-read.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,16 +177,18 @@ struct trace_event_t
public:
bool is_filtered_out = false;

int pid; // event process id
uint32_t id; // event id
uint32_t cpu; // cpu this event was hit on
int64_t ts; // timestamp

uint32_t flags = 0; // TRACE_FLAGS_IRQS_OFF, TRACE_FLAG_HARDIRQ, TRACE_FLAG_SOFTIRQ
uint32_t seqno = 0; // event seqno (from fields)
uint32_t id_start = INVALID_ID; // start event if this is a graph sequence event (ie amdgpu_sched_run_job, fence_signaled)
int pid; // event process id
uint32_t id; // event id
uint32_t cpu; // cpu this event was hit on
int64_t ts; // timestamp

uint32_t flags = 0; // TRACE_FLAGS_IRQS_OFF, TRACE_FLAG_HARDIRQ, TRACE_FLAG_SOFTIRQ
uint32_t seqno = 0; // event seqno (from fields)
uint32_t id_start = INVALID_ID; // start event if this is a graph sequence event (ie amdgpu_sched_run_job, fence_signaled)
uint32_t graph_row_id = 0;
int crtc = -1; // drm_vblank_event crtc (or -1)
int crtc = -1; // drm_vblank_event crtc (or -1)
int64_t vblank_ts = INT64_MAX; // time-stamp that is passed with the drm_event_vblank event
bool vblank_ts_high_prec = false; // denotes whether or not the hardware timestamp is high-precision

uint32_t color = 0; // color of the event (or 0 for default)

Expand All @@ -206,13 +208,14 @@ struct trace_event_t
event_field_t *fields = nullptr;

public:
bool is_fence_signaled() const { return !!( flags & TRACE_FLAG_FENCE_SIGNALED ); }
bool is_ftrace_print() const { return !!( flags & TRACE_FLAG_FTRACE_PRINT ); }
bool is_vblank() const { return !!( flags & TRACE_FLAG_VBLANK ); }
bool is_timeline() const { return !!( flags & TRACE_FLAG_TIMELINE ); }
bool is_sched_switch() const { return !!( flags & TRACE_FLAG_SCHED_SWITCH ); }

bool has_duration() const { return duration != INT64_MAX; }
bool is_fence_signaled() const { return !!( flags & TRACE_FLAG_FENCE_SIGNALED ); }
bool is_ftrace_print() const { return !!( flags & TRACE_FLAG_FTRACE_PRINT ); }
bool is_vblank() const { return !!( flags & TRACE_FLAG_VBLANK ); }
bool is_timeline() const { return !!( flags & TRACE_FLAG_TIMELINE ); }
bool is_sched_switch() const { return !!( flags & TRACE_FLAG_SCHED_SWITCH ); }

bool has_duration() const { return duration != INT64_MAX; }
int64_t get_vblank_ts(bool want_high_prec) const { return want_high_prec && (vblank_ts != INT64_MAX) && vblank_ts_high_prec ? vblank_ts : ts; }

const char *get_timeline_name( const char *def = NULL ) const
{
Expand Down