Skip to content

Commit

Permalink
Support for ETL gpu events
Browse files Browse the repository at this point in the history
Only the gfx timeline is supported. I need to investigate more to
figure out how compute is handled.

Pre-emption is not handled correctly either.

The events emulate amgpu linux events to get the graph going in a
quick and dirty fashion.
  • Loading branch information
lostgoat authored and mikesart committed Apr 26, 2019
1 parent b4db7bc commit 0ac7305
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 44 deletions.
13 changes: 13 additions & 0 deletions src/etl_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@
#include <windows.h>
#include <tdh.h>

// This enum is in the MS docs that references a header called Dxetwevt.h,
// but that header is nowhere to be found.
typedef enum _DXGKETW_QUEUE_PACKET_TYPE {
DXGKETW_RENDER_COMMAND_BUFFER = 0,
DXGKETW_DEFERRED_COMMAND_BUFFER = 1,
DXGKETW_SYSTEM_COMMAND_BUFFER = 2,
DXGKETW_MMIOFLIP_COMMAND_BUFFER = 3,
DXGKETW_WAIT_COMMAND_BUFFER = 4,
DXGKETW_SIGNAL_COMMAND_BUFFER = 5,
DXGKETW_DEVICE_COMMAND_BUFFER = 6,
DXGKETW_SOFTWARE_COMMAND_BUFFER = 7
} DXGKETW_QUEUE_PACKET_TYPE;

DWORD DumpEventMetadataField( TRACE_EVENT_INFO* pinfo, DWORD i, USHORT indent );
DWORD DumpEventMetadata( PTRACE_EVENT_INFO info );
DWORD DumpEvent( PEVENT_RECORD pEvent, PTRACE_EVENT_INFO pInfo );
Expand Down
113 changes: 69 additions & 44 deletions src/gpuvis_etl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,22 @@ class vsync_entry_t : public event_entry_t
}
};

class queue_packet_header_entry_t : public event_entry_t
{
public:
void *ctx;
uint32_t ptype;
uint32_t seq;

queue_packet_header_entry_t( etl_reader_t::etl_reader_cb_data_t *cbdata ) :
event_entry_t( cbdata )
{
ETL_EXTRACT( 0, ctx );
ETL_EXTRACT( 1, ptype );
ETL_EXTRACT( 2, seq );
}
};

/**
* Parses the ETL information stream
*
Expand All @@ -560,6 +576,7 @@ class etl_parser_t
class __declspec( uuid( "{802ec45a-1e99-4b83-9920-87c98277ba9d}" ) ) kDxcProvider;

static const int kDxcVsyncTaskId = 10;
static const int kDxcQueuePacketTaskId = 9;

public:
// Forward the callback to the right object
Expand Down Expand Up @@ -636,14 +653,15 @@ class etl_parser_t
break;
}
break;
case kDxcQueuePacketTaskId:
ret = process_queue_packet_entry( cbdata );
break;
}
}
else
{
//DumpEventMetadata( info );
//DumpProperties( event, info );
//std::string out;
//tdh_extract( event, info, 0, out );
}

return ret;
Expand Down Expand Up @@ -829,58 +847,65 @@ class etl_parser_t

return mCallback( event );
}
};

int read_etl_file( const char *file, StrPool &strpool, trace_info_t &trace_info, EventCallback &cb )
{
etl_parser_t parser( file, strpool, trace_info, cb );
return parser.process();

/*
// Find the lowest ts value in the trace file
trace_info.min_file_ts = std::min< int64_t >( trace_info.min_file_ts, record->ts );
trace_info.cpu_info.resize( handle->cpus );
for ( size_t cpu = 0; cpu < (size_t)handle->cpus; cpu++ )
int process_queue_packet_entry( etl_reader_t::etl_reader_cb_data_t *cbdata )
{
cpu_info_t &cpu_info = trace_info.cpu_info[cpu];
pevent_record_t *record = tracecmd_peek_data( handle, cpu );
cpu_info.file_offset = handle->cpu_data[cpu].file_offset;
cpu_info.file_size = handle->cpu_data[cpu].file_size;
int err = -1;
trace_event_t event;
std::string timeline = "";
queue_packet_header_entry_t header( cbdata );
UCHAR opcode = cbdata->event->EventHeader.EventDescriptor.Opcode;

if ( cpu < handle->cpustats.size() )
switch ( header.ptype )
{
const char *stats = handle->cpustats[cpu].c_str();
cpu_info.entries = geti64( stats, "entries:" );
cpu_info.overrun = geti64( stats, "overrun:" );
cpu_info.commit_overrun = geti64( stats, "commit overrun:" );
cpu_info.bytes = geti64( stats, "bytes:" );
cpu_info.oldest_event_ts = getf64( stats, "oldest event ts:" );
cpu_info.now_ts = getf64( stats, "now ts:" );
cpu_info.dropped_events = geti64( stats, "dropped events:" );
cpu_info.read_events = geti64( stats, "read events:" );
if ( cpu_info.oldest_event_ts )
cpu_info.oldest_event_ts -= trace_info.min_file_ts;
if ( cpu_info.now_ts )
cpu_info.now_ts -= trace_info.min_file_ts;
case DXGKETW_RENDER_COMMAND_BUFFER:
case DXGKETW_DEFERRED_COMMAND_BUFFER:
case DXGKETW_SYSTEM_COMMAND_BUFFER:
timeline = "gfx";
break;
default:
//ETL_DUMP();
return -1;
}

if ( record )
switch ( opcode )
{
cpu_info.min_ts = record->ts - trace_info.min_file_ts;
if ( cpu_info.overrun && trace_info.trim_trace )
trim_ts = std::max< unsigned long long >( trim_ts, record->ts );
case EVENT_TRACE_TYPE_START:
event.name = mStrPool.getstr( "amdgpu_cs_ioctl" ); // For dat compatibility
event.flags = TRACE_FLAG_SW_QUEUE;
break;
case EVENT_TRACE_TYPE_INFO:
event.name = mStrPool.getstr( "amdgpu_sched_run_job" ); // For dat compatibility
event.flags = TRACE_FLAG_HW_QUEUE;
break;
case EVENT_TRACE_TYPE_STOP:
event.name = mStrPool.getstr( "fence_signaled" ); // For dat compatibility
event.flags = TRACE_FLAG_FENCE_SIGNALED;
break;
}

err = process_event_entry( header, event );
if ( err )
return err;

event.system = mStrPool.getstr( "QueuePacket" );

event.numfields = 2;
event.fields = new event_field_t[event.numfields];
event.fields[0].key = mStrPool.getstr( "timeline" );
event.fields[0].value = mStrPool.getstr( timeline.c_str() );
event.fields[1].key = mStrPool.getstr( "context" );
event.fields[1].value = mStrPool.getstrf( "0x%xll", header.ctx );
event.seqno = header.seq;

return mCallback( event );
}
};

// Scoot to tracestart time if it was set
trim_ts = std::max< unsigned long long >( trim_ts, trace_info.min_file_ts + trace_info.m_tracestart );
*/
return 0;
int read_etl_file( const char *file, StrPool &strpool, trace_info_t &trace_info, EventCallback &cb )
{
etl_parser_t parser( file, strpool, trace_info, cb );
return parser.process();
}

#else
Expand Down

0 comments on commit 0ac7305

Please sign in to comment.