mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-27 00:04:35 +00:00
Trace vsyncs.
This commit is contained in:
parent
1fff99ebb0
commit
0da6342a86
@ -21,23 +21,28 @@
|
|||||||
# include "../common/TracyAlloc.hpp"
|
# include "../common/TracyAlloc.hpp"
|
||||||
# include "../common/TracySystem.hpp"
|
# include "../common/TracySystem.hpp"
|
||||||
# include "TracyProfiler.hpp"
|
# include "TracyProfiler.hpp"
|
||||||
|
# include "TracyThread.hpp"
|
||||||
|
|
||||||
namespace tracy
|
namespace tracy
|
||||||
{
|
{
|
||||||
|
|
||||||
DEFINE_GUID ( /* ce1dbfb4-137e-4da6-87b0-3f59aa102cbc */
|
struct __declspec(uuid("{ce1dbfb4-137e-4da6-87b0-3f59aa102cbc}")) PERFINFOGUID;
|
||||||
PerfInfoGuid,
|
static const auto PerfInfoGuid = __uuidof(PERFINFOGUID);
|
||||||
0xce1dbfb4,
|
|
||||||
0x137e,
|
struct __declspec(uuid("{802EC45A-1E99-4B83-9920-87C98277BA9D}")) DXGKRNLGUID;
|
||||||
0x4da6,
|
static const auto DxgKrnlGuid = __uuidof(DXGKRNLGUID);
|
||||||
0x87, 0xb0, 0x3f, 0x59, 0xaa, 0x10, 0x2c, 0xbc
|
|
||||||
);
|
|
||||||
|
|
||||||
static TRACEHANDLE s_traceHandle;
|
static TRACEHANDLE s_traceHandle;
|
||||||
static TRACEHANDLE s_traceHandle2;
|
static TRACEHANDLE s_traceHandle2;
|
||||||
static EVENT_TRACE_PROPERTIES* s_prop;
|
static EVENT_TRACE_PROPERTIES* s_prop;
|
||||||
static DWORD s_pid;
|
static DWORD s_pid;
|
||||||
|
|
||||||
|
static EVENT_TRACE_PROPERTIES* s_propVsync;
|
||||||
|
static TRACEHANDLE s_traceHandleVsync;
|
||||||
|
static TRACEHANDLE s_traceHandleVsync2;
|
||||||
|
Thread* s_threadVsync = nullptr;
|
||||||
|
|
||||||
struct CSwitch
|
struct CSwitch
|
||||||
{
|
{
|
||||||
uint32_t newThreadId;
|
uint32_t newThreadId;
|
||||||
@ -85,6 +90,19 @@ struct StackWalkEvent
|
|||||||
uint64_t stack[192];
|
uint64_t stack[192];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VSyncInfo
|
||||||
|
{
|
||||||
|
void* dxgAdapter;
|
||||||
|
uint32_t vidPnTargetId;
|
||||||
|
uint64_t scannedPhysicalAddress;
|
||||||
|
uint32_t vidPnSourceId;
|
||||||
|
uint32_t frameNumber;
|
||||||
|
int64_t frameQpcTime;
|
||||||
|
void* hFlipDevice;
|
||||||
|
uint32_t flipType;
|
||||||
|
uint64_t flipFenceId;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
extern "C" typedef DWORD (WINAPI *t_GetProcessIdOfThread)( HANDLE );
|
extern "C" typedef DWORD (WINAPI *t_GetProcessIdOfThread)( HANDLE );
|
||||||
extern "C" typedef DWORD (WINAPI *t_GetProcessImageFileNameA)( HANDLE, LPSTR, DWORD );
|
extern "C" typedef DWORD (WINAPI *t_GetProcessImageFileNameA)( HANDLE, LPSTR, DWORD );
|
||||||
@ -181,6 +199,133 @@ void WINAPI EventRecordCallback( PEVENT_RECORD record )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr const char* VsyncName[] = {
|
||||||
|
"[0] Vsync",
|
||||||
|
"[1] Vsync",
|
||||||
|
"[2] Vsync",
|
||||||
|
"[3] Vsync",
|
||||||
|
"[4] Vsync",
|
||||||
|
"[5] Vsync",
|
||||||
|
"[6] Vsync",
|
||||||
|
"[7] Vsync",
|
||||||
|
"Vsync"
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t VsyncTarget[8] = {};
|
||||||
|
|
||||||
|
void WINAPI EventRecordCallbackVsync( PEVENT_RECORD record )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !GetProfiler().IsConnected() ) return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const auto& hdr = record->EventHeader;
|
||||||
|
assert( hdr.ProviderId.Data1 == 0x802EC45A );
|
||||||
|
assert( hdr.EventDescriptor.Id == 0x0011 );
|
||||||
|
|
||||||
|
const auto vs = (const VSyncInfo*)record->UserData;
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if( VsyncTarget[idx] == 0 )
|
||||||
|
{
|
||||||
|
VsyncTarget[idx] = vs->vidPnTargetId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if( VsyncTarget[idx] == vs->vidPnTargetId )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while( ++idx < 8 );
|
||||||
|
|
||||||
|
const char* name = "Vsync";
|
||||||
|
TracyLfqPrepare( QueueType::FrameMarkMsg );
|
||||||
|
MemWrite( &item->frameMark.time, hdr.TimeStamp.QuadPart );
|
||||||
|
MemWrite( &item->frameMark.name, uint64_t( VsyncName[idx] ) );
|
||||||
|
TracyLfqCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetupVsync()
|
||||||
|
{
|
||||||
|
const auto psz = sizeof( EVENT_TRACE_PROPERTIES ) + MAX_PATH;
|
||||||
|
s_propVsync = (EVENT_TRACE_PROPERTIES*)tracy_malloc( psz );
|
||||||
|
memset( s_propVsync, 0, sizeof( EVENT_TRACE_PROPERTIES ) );
|
||||||
|
s_propVsync->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
|
||||||
|
s_propVsync->Wnode.BufferSize = psz;
|
||||||
|
#ifdef TRACY_TIMER_QPC
|
||||||
|
s_propVsync->Wnode.ClientContext = 1;
|
||||||
|
#else
|
||||||
|
s_propVsync->Wnode.ClientContext = 3;
|
||||||
|
#endif
|
||||||
|
s_propVsync->LoggerNameOffset = sizeof( EVENT_TRACE_PROPERTIES );
|
||||||
|
strcpy( ((char*)s_propVsync) + sizeof( EVENT_TRACE_PROPERTIES ), "TracyVsync" );
|
||||||
|
|
||||||
|
auto backup = tracy_malloc( psz );
|
||||||
|
memcpy( backup, s_propVsync, psz );
|
||||||
|
|
||||||
|
const auto controlStatus = ControlTraceA( 0, "TracyVsync", s_propVsync, EVENT_TRACE_CONTROL_STOP );
|
||||||
|
if( controlStatus != ERROR_SUCCESS && controlStatus != ERROR_WMI_INSTANCE_NOT_FOUND )
|
||||||
|
{
|
||||||
|
tracy_free( backup );
|
||||||
|
tracy_free( s_propVsync );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy( s_propVsync, backup, psz );
|
||||||
|
tracy_free( backup );
|
||||||
|
|
||||||
|
const auto startStatus = StartTraceA( &s_traceHandleVsync, "TracyVsync", s_propVsync );
|
||||||
|
if( startStatus != ERROR_SUCCESS )
|
||||||
|
{
|
||||||
|
tracy_free( s_propVsync );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVENT_FILTER_EVENT_ID fe = {};
|
||||||
|
fe.FilterIn = TRUE;
|
||||||
|
fe.Count = 1;
|
||||||
|
fe.Events[0] = 0x0011; // VSyncDPC_Info
|
||||||
|
|
||||||
|
EVENT_FILTER_DESCRIPTOR desc = {};
|
||||||
|
desc.Ptr = (ULONGLONG)&fe;
|
||||||
|
desc.Size = sizeof( fe );
|
||||||
|
desc.Type = EVENT_FILTER_TYPE_EVENT_ID;
|
||||||
|
|
||||||
|
ENABLE_TRACE_PARAMETERS params = {};
|
||||||
|
params.Version = ENABLE_TRACE_PARAMETERS_VERSION_2;
|
||||||
|
params.EnableProperty = EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0;
|
||||||
|
params.SourceId = s_propVsync->Wnode.Guid;
|
||||||
|
params.EnableFilterDesc = &desc;
|
||||||
|
params.FilterDescCount = 1;
|
||||||
|
|
||||||
|
uint64_t mask = 0x4000000000000001; // Microsoft_Windows_DxgKrnl_Performance | Base
|
||||||
|
EnableTraceEx2( s_traceHandleVsync, &DxgKrnlGuid, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_INFORMATION, mask, mask, 0, ¶ms );
|
||||||
|
|
||||||
|
char loggerName[MAX_PATH];
|
||||||
|
strcpy( loggerName, "TracyVsync" );
|
||||||
|
|
||||||
|
EVENT_TRACE_LOGFILEA log = {};
|
||||||
|
log.LoggerName = loggerName;
|
||||||
|
log.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_RAW_TIMESTAMP;
|
||||||
|
log.EventRecordCallback = EventRecordCallbackVsync;
|
||||||
|
|
||||||
|
s_traceHandleVsync2 = OpenTraceA( &log );
|
||||||
|
if( s_traceHandleVsync2 == (TRACEHANDLE)INVALID_HANDLE_VALUE )
|
||||||
|
{
|
||||||
|
CloseTrace( s_traceHandleVsync );
|
||||||
|
tracy_free( s_propVsync );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_threadVsync = (Thread*)tracy_malloc( sizeof( Thread ) );
|
||||||
|
new(s_threadVsync) Thread( [] (void*) {
|
||||||
|
SetThreadName( "Tracy Vsync" );
|
||||||
|
ProcessTrace( &s_traceHandleVsync2, 1, nullptr, nullptr );
|
||||||
|
}, nullptr );
|
||||||
|
}
|
||||||
|
|
||||||
bool SysTraceStart( int64_t& samplingPeriod )
|
bool SysTraceStart( int64_t& samplingPeriod )
|
||||||
{
|
{
|
||||||
if( !_GetThreadDescription ) _GetThreadDescription = (t_GetThreadDescription)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "GetThreadDescription" );
|
if( !_GetThreadDescription ) _GetThreadDescription = (t_GetThreadDescription)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "GetThreadDescription" );
|
||||||
@ -289,11 +434,21 @@ bool SysTraceStart( int64_t& samplingPeriod )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetupVsync();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SysTraceStop()
|
void SysTraceStop()
|
||||||
{
|
{
|
||||||
|
if( s_threadVsync )
|
||||||
|
{
|
||||||
|
CloseTrace( s_traceHandleVsync2 );
|
||||||
|
CloseTrace( s_traceHandleVsync );
|
||||||
|
s_threadVsync->~Thread();
|
||||||
|
tracy_free( s_threadVsync );
|
||||||
|
}
|
||||||
|
|
||||||
CloseTrace( s_traceHandle2 );
|
CloseTrace( s_traceHandle2 );
|
||||||
CloseTrace( s_traceHandle );
|
CloseTrace( s_traceHandle );
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user