mirror of
https://github.com/wolfpld/tracy.git
synced 2026-06-08 00:23:47 +00:00
Compare commits
7 Commits
fc5318dcad
...
mesh-debug
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d475c3022 | ||
|
|
e7acf05a71 | ||
|
|
41c45e2d2b | ||
|
|
d4db8e2512 | ||
|
|
a25f541297 | ||
|
|
abacf6302b | ||
|
|
5d673eb8f2 |
@@ -58,11 +58,15 @@
|
||||
#define TracyAllocS(x,y,z)
|
||||
#define TracyFreeS(x,y)
|
||||
|
||||
#define TracyMeshTri(v0,v1,v2,v3,v4,v5)
|
||||
#define TracyMeshEnd
|
||||
|
||||
#else
|
||||
|
||||
#include "client/TracyLock.hpp"
|
||||
#include "client/TracyProfiler.hpp"
|
||||
#include "client/TracyScoped.hpp"
|
||||
#include "client/TracyMesh.hpp"
|
||||
|
||||
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||
# define ZoneNamed( varname, active ) static const tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
|
||||
@@ -143,6 +147,9 @@
|
||||
# define TracyFreeS( ptr, depth ) TracyFree( ptr )
|
||||
#endif
|
||||
|
||||
#define TracyMeshTri( x0, y0, x1, y1, x2, y2 ) tracy::mesh::MeshTri( x0, y0, x1, y1, x2, y2 )
|
||||
#define TracyMeshEnd tracy::mesh::MeshEnd();
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
40
client/TracyMesh.hpp
Normal file
40
client/TracyMesh.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef __TRACYMESH_HPP__
|
||||
#define __TRACYMESH_HPP__
|
||||
|
||||
#include "TracyProfiler.hpp"
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
namespace mesh
|
||||
{
|
||||
|
||||
static void MeshTri( float x0, float y0, float x1, float y1, float x2, float y2 )
|
||||
{
|
||||
Magic magic;
|
||||
auto token = GetToken();
|
||||
auto& tail = token->get_tail_index();
|
||||
auto item = token->enqueue_begin( magic );
|
||||
MemWrite( &item->hdr.type, QueueType::MeshTri );
|
||||
MemWrite( &item->meshTri.x0, x0 );
|
||||
MemWrite( &item->meshTri.y0, y0 );
|
||||
MemWrite( &item->meshTri.x1, x1 );
|
||||
MemWrite( &item->meshTri.y1, y1 );
|
||||
MemWrite( &item->meshTri.x2, x2 );
|
||||
MemWrite( &item->meshTri.y2, y2 );
|
||||
tail.store( magic + 1, std::memory_order_release );
|
||||
}
|
||||
|
||||
static void MeshEnd()
|
||||
{
|
||||
Magic magic;
|
||||
auto token = GetToken();
|
||||
auto& tail = token->get_tail_index();
|
||||
auto item = token->enqueue_begin( magic );
|
||||
MemWrite( &item->hdr.type, QueueType::MeshEnd );
|
||||
tail.store( magic + 1, std::memory_order_release );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
enum : uint32_t { ProtocolVersion = 14 };
|
||||
enum : uint32_t { ProtocolVersion = 15 };
|
||||
enum : uint32_t { BroadcastVersion = 0 };
|
||||
|
||||
using lz4sz_t = uint32_t;
|
||||
|
||||
@@ -56,6 +56,8 @@ enum class QueueType : uint8_t
|
||||
CallstackFrameSize,
|
||||
CallstackFrame,
|
||||
SysTimeReport,
|
||||
MeshTri,
|
||||
MeshEnd,
|
||||
StringData,
|
||||
ThreadName,
|
||||
CustomStringData,
|
||||
@@ -297,6 +299,13 @@ struct QueueSysTime
|
||||
float sysTime;
|
||||
};
|
||||
|
||||
struct QueueMeshTri
|
||||
{
|
||||
float x0, y0;
|
||||
float x1, y1;
|
||||
float x2, y2;
|
||||
};
|
||||
|
||||
struct QueueHeader
|
||||
{
|
||||
union
|
||||
@@ -342,6 +351,7 @@ struct QueueItem
|
||||
QueueCallstackFrame callstackFrame;
|
||||
QueueCrashReport crashReport;
|
||||
QueueSysTime sysTime;
|
||||
QueueMeshTri meshTri;
|
||||
};
|
||||
};
|
||||
#pragma pack()
|
||||
@@ -399,6 +409,8 @@ static const size_t QueueDataSize[] = {
|
||||
sizeof( QueueHeader ) + sizeof( QueueCallstackFrameSize ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueCallstackFrame ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueSysTime ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueMeshTri ),
|
||||
sizeof( QueueHeader ), // mesh end
|
||||
// keep all QueueStringTransfer below
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // string data
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // thread name
|
||||
|
||||
@@ -221,6 +221,16 @@ struct CrashEvent
|
||||
|
||||
enum { CrashEventSize = sizeof( CrashEvent ) };
|
||||
|
||||
|
||||
struct MeshTriangle
|
||||
{
|
||||
float x0, y0;
|
||||
float x1, y1;
|
||||
float x2, y2;
|
||||
};
|
||||
|
||||
enum { MeshTriangleSize = sizeof( MeshTriangle ) };
|
||||
|
||||
#pragma pack()
|
||||
|
||||
|
||||
@@ -325,6 +335,7 @@ struct FrameEvent
|
||||
int64_t start;
|
||||
int64_t end;
|
||||
int32_t frameImage;
|
||||
Vector<Vector<MeshTriangle>> mesh;
|
||||
};
|
||||
|
||||
struct FrameData
|
||||
|
||||
@@ -717,6 +717,7 @@ bool View::DrawImpl()
|
||||
if( m_goToFrame ) DrawGoToFrame();
|
||||
if( m_lockInfoWindow != InvalidId ) DrawLockInfoWindow();
|
||||
if( m_showPlayback ) DrawPlayback();
|
||||
if( m_meshDebug >= 0 ) DrawMeshDebug();
|
||||
|
||||
if( m_zoomAnim.active )
|
||||
{
|
||||
@@ -9569,9 +9570,178 @@ void View::DrawPlayback()
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox( "Zoom 2x", &m_playback.zoom );
|
||||
TextFocused( "Timestamp:", TimeToString( tstart - m_worker.GetTimeBegin() ) );
|
||||
|
||||
const auto& frame = m_worker.GetFramesBase()->frames[fi->frameRef];
|
||||
if( !frame.mesh.empty() )
|
||||
{
|
||||
if( ImGui::Button( "Mesh debug" ) )
|
||||
{
|
||||
m_meshDebug = fi->frameRef;
|
||||
m_meshDrawList = ~0;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
const uint32_t MeshColors[6] = {
|
||||
0xFFFF8888,
|
||||
0xFF88FF88,
|
||||
0xFF8888FF,
|
||||
0xFFAAAAAA,
|
||||
0xFFFFFF44,
|
||||
0xFFFF44FF
|
||||
};
|
||||
|
||||
static ImVec2 GetRegionRect()
|
||||
{
|
||||
const auto region = ImGui::GetContentRegionAvail();
|
||||
const auto v = std::min( region.x, region.y );
|
||||
return ImVec2( v, v );
|
||||
}
|
||||
|
||||
void View::DrawMeshDebug()
|
||||
{
|
||||
assert( m_meshDebug >= 0 );
|
||||
|
||||
bool show = true;
|
||||
ImGui::Begin( "Mesh debug", &show );
|
||||
|
||||
ImGui::Columns( 2 );
|
||||
TextFocused( "Mesh debug frame", RealToString( m_meshDebug, true ) );
|
||||
TextFocused( "X range", RealToString( m_meshx1 - m_meshx0, true ) );
|
||||
TextFocused( "Y range", RealToString( m_meshy1 - m_meshy0, true ) );
|
||||
|
||||
const auto& meshList = m_worker.GetFramesBase()->frames[m_meshDebug].mesh;
|
||||
assert( !meshList.empty() );
|
||||
|
||||
const auto msz = meshList.size();
|
||||
for( size_t i=0; i<msz; i++ )
|
||||
{
|
||||
const auto bit = 1 << i;
|
||||
bool enabled = m_meshDrawList & bit;
|
||||
char buf[128];
|
||||
sprintf( buf, "Mesh %llu (%llu tris)", i, meshList[i].size() );
|
||||
SmallCheckbox( buf, &enabled );
|
||||
if( enabled ) { m_meshDrawList |= bit; } else { m_meshDrawList &= ~bit; }
|
||||
}
|
||||
|
||||
if( ImGui::SmallButton( "Auto fit" ) )
|
||||
{
|
||||
float minx = std::numeric_limits<float>::max();
|
||||
float miny = std::numeric_limits<float>::max();
|
||||
float maxx = std::numeric_limits<float>::min();
|
||||
float maxy = std::numeric_limits<float>::min();
|
||||
int bit = 1;
|
||||
for( auto& mesh : meshList )
|
||||
{
|
||||
if( m_meshDrawList & bit )
|
||||
{
|
||||
for( auto& tri : mesh )
|
||||
{
|
||||
minx = std::min( { minx, tri.x0, tri.x1, tri.x2 } );
|
||||
maxx = std::max( { maxx, tri.x0, tri.x1, tri.x2 } );
|
||||
miny = std::min( { miny, tri.y0, tri.y1, tri.y2 } );
|
||||
maxy = std::max( { maxy, tri.y0, tri.y1, tri.y2 } );
|
||||
}
|
||||
}
|
||||
bit <<= 1;
|
||||
}
|
||||
const auto dx = maxx - minx;
|
||||
const auto dy = maxy - miny;
|
||||
const auto dd = std::max( dx, dy ) * 0.5f;
|
||||
const auto ax = ( minx + maxx ) * 0.5f;
|
||||
const auto ay = ( miny + maxy ) * 0.5f;
|
||||
m_meshx0 = ax - dd;
|
||||
m_meshx1 = ax + dd;
|
||||
m_meshy0 = ay - dd;
|
||||
m_meshy1 = ay + dd;
|
||||
}
|
||||
|
||||
ImGui::NextColumn();
|
||||
|
||||
auto& io = ImGui::GetIO();
|
||||
auto draw = ImGui::GetWindowDrawList();
|
||||
const auto wpos = ImGui::GetWindowPos() + ImGui::GetCursorPos();
|
||||
const auto region = GetRegionRect();
|
||||
draw->AddRectFilled( wpos, wpos + region, 0xFF444444 );
|
||||
draw->PushClipRect( wpos, wpos + region, true );
|
||||
|
||||
if( ImGui::IsMouseHoveringRect( wpos, wpos + region ) )
|
||||
{
|
||||
const auto px = ( m_meshx1 - m_meshx0 ) / region.x;
|
||||
if( ImGui::IsMouseDragging( 1, 0 ) )
|
||||
{
|
||||
auto delta = ImGui::GetMouseDragDelta( 1, 0 );
|
||||
m_meshx0 -= delta.x * px;
|
||||
m_meshx1 -= delta.x * px;
|
||||
m_meshy0 -= delta.y * px;
|
||||
m_meshy1 -= delta.y * px;
|
||||
io.MouseClickedPos[1] = io.MousePos;
|
||||
}
|
||||
|
||||
const auto wheel = io.MouseWheel;
|
||||
if( wheel != 0 )
|
||||
{
|
||||
const auto mouse = io.MousePos - wpos;
|
||||
const auto p = ImVec2( mouse.x / region.x, mouse.y / region.y );
|
||||
|
||||
const auto xZoomSpan = m_meshx1 - m_meshx0;
|
||||
const auto yZoomSpan = m_meshy1 - m_meshy0;
|
||||
const auto p1x = xZoomSpan * p.x;
|
||||
const auto p2x = xZoomSpan - p1x;
|
||||
const auto p1y = yZoomSpan * p.y;
|
||||
const auto p2y = yZoomSpan - p1y;
|
||||
|
||||
if( wheel > 0 )
|
||||
{
|
||||
m_meshx0 += p1x * 0.25;
|
||||
m_meshx1 -= p2x * 0.25;
|
||||
m_meshy0 += p1y * 0.25;
|
||||
m_meshy1 -= p2y * 0.25;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_meshx0 -= p1x * 0.25;
|
||||
m_meshx1 += p2x * 0.25;
|
||||
m_meshy0 -= p1y * 0.25;
|
||||
m_meshy1 += p2y * 0.25;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto mulx = region.x / ( m_meshx1 - m_meshx0 );
|
||||
const auto muly = region.y / ( m_meshy1 - m_meshy0 );
|
||||
for( int idx=meshList.size()-1; idx>=0; idx-- )
|
||||
{
|
||||
if( m_meshDrawList & ( 1 << idx ) )
|
||||
{
|
||||
for( auto& tri : meshList[idx] )
|
||||
{
|
||||
const auto x0 = ( tri.x0 - m_meshx0 ) * mulx;
|
||||
const auto x1 = ( tri.x1 - m_meshx0 ) * mulx;
|
||||
const auto x2 = ( tri.x2 - m_meshx0 ) * mulx;
|
||||
const auto y0 = ( tri.y0 - m_meshy0 ) * muly;
|
||||
const auto y1 = ( tri.y1 - m_meshy0 ) * muly;
|
||||
const auto y2 = ( tri.y2 - m_meshy0 ) * muly;
|
||||
|
||||
const auto col = MeshColors[idx%6];
|
||||
|
||||
draw->AddLine( wpos + ImVec2( x0, y0 ), wpos + ImVec2( x1, y1 ), col );
|
||||
draw->AddLine( wpos + ImVec2( x1, y1 ), wpos + ImVec2( x2, y2 ), col );
|
||||
draw->AddLine( wpos + ImVec2( x2, y2 ), wpos + ImVec2( x0, y0 ), col );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw->PopClipRect();
|
||||
|
||||
ImGui::NextColumn();
|
||||
ImGui::EndColumns();
|
||||
ImGui::End();
|
||||
if( !show ) m_meshDebug = -1;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void View::ListMemData( T ptr, T end, std::function<void(T&)> DrawAddress, const char* id, int64_t startTime )
|
||||
{
|
||||
|
||||
@@ -133,6 +133,7 @@ private:
|
||||
void DrawGoToFrame();
|
||||
void DrawLockInfoWindow();
|
||||
void DrawPlayback();
|
||||
void DrawMeshDebug();
|
||||
|
||||
template<class T>
|
||||
void ListMemData( T ptr, T end, std::function<void(T&)> DrawAddress, const char* id = nullptr, int64_t startTime = -1 );
|
||||
@@ -542,6 +543,13 @@ private:
|
||||
bool sync = false;
|
||||
bool zoom = false;
|
||||
} m_playback;
|
||||
|
||||
int m_meshDebug = -1;
|
||||
uint64_t m_meshDrawList;
|
||||
double m_meshx0 = -1;
|
||||
double m_meshy0 = -1;
|
||||
double m_meshx1 = 1;
|
||||
double m_meshy1 = 1;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -394,15 +394,28 @@ Worker::Worker( FileRead& f, EventType::Type eventMask )
|
||||
{
|
||||
for( uint64_t j=0; j<fsz; j++ )
|
||||
{
|
||||
new(&ptr->frames[j].mesh) Vector<Vector<MeshTriangle>>();
|
||||
ptr->frames[j].start = ReadTimeOffset( f, refTime );
|
||||
ptr->frames[j].end = -1;
|
||||
f.Read( &ptr->frames[j].frameImage, sizeof( int32_t ) );
|
||||
uint64_t msz;
|
||||
f.Read( &msz, sizeof( msz ) );
|
||||
for( uint64_t k=0; k<msz; k++ )
|
||||
{
|
||||
Vector<MeshTriangle> mesh;
|
||||
uint64_t dsz;
|
||||
f.Read( &dsz, sizeof( dsz ) );
|
||||
mesh.reserve_exact( dsz, m_slab );
|
||||
f.Read( mesh.data(), sizeof( MeshTriangle ) * dsz );
|
||||
ptr->frames[j].mesh.push_back( std::move( mesh ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( uint64_t j=0; j<fsz; j++ )
|
||||
{
|
||||
new(&ptr->frames[j].mesh) Vector<Vector<MeshTriangle>>();
|
||||
ptr->frames[j].start = ReadTimeOffset( f, refTime );
|
||||
ptr->frames[j].end = ReadTimeOffset( f, refTime );
|
||||
f.Read( &ptr->frames[j].frameImage, sizeof( int32_t ) );
|
||||
@@ -2780,6 +2793,12 @@ bool Worker::Process( const QueueItem& ev )
|
||||
case QueueType::SysTimeReport:
|
||||
ProcessSysTime( ev.sysTime );
|
||||
break;
|
||||
case QueueType::MeshEnd:
|
||||
ProcessMeshEnd();
|
||||
break;
|
||||
case QueueType::MeshTri:
|
||||
ProcessMeshTri( ev.meshTri );
|
||||
break;
|
||||
default:
|
||||
assert( false );
|
||||
break;
|
||||
@@ -3804,6 +3823,26 @@ void Worker::ProcessSysTime( const QueueSysTime& ev )
|
||||
}
|
||||
}
|
||||
|
||||
void Worker::ProcessMeshEnd()
|
||||
{
|
||||
auto& mesh = m_data.framesBase->frames.back().mesh.push_next();
|
||||
const auto sz = m_data.meshStaging.size();
|
||||
mesh.reserve_exact( sz, m_slab );
|
||||
memcpy( mesh.data(), m_data.meshStaging.data(), sizeof( MeshTriangle ) * sz );
|
||||
m_data.meshStaging.clear();
|
||||
}
|
||||
|
||||
void Worker::ProcessMeshTri( const QueueMeshTri& ev )
|
||||
{
|
||||
auto& tri = m_data.meshStaging.push_next();
|
||||
tri.x0 = ev.x0;
|
||||
tri.y0 = ev.y0;
|
||||
tri.x1 = ev.x1;
|
||||
tri.y1 = ev.y1;
|
||||
tri.x2 = ev.x2;
|
||||
tri.y2 = ev.y2;
|
||||
}
|
||||
|
||||
void Worker::MemAllocChanged( int64_t time )
|
||||
{
|
||||
const auto val = (double)m_data.memory.usage;
|
||||
@@ -4252,6 +4291,14 @@ void Worker::Write( FileWrite& f )
|
||||
{
|
||||
WriteTimeOffset( f, refTime, fe.start );
|
||||
f.Write( &fe.frameImage, sizeof( fe.frameImage ) );
|
||||
sz = fe.mesh.size();
|
||||
f.Write( &sz, sizeof( sz ) );
|
||||
for( auto& mesh : fe.mesh )
|
||||
{
|
||||
sz = mesh.size();
|
||||
f.Write( &sz, sizeof( sz ) );
|
||||
f.Write( mesh.data(), sizeof( MeshTriangle ) * sz );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -188,6 +188,8 @@ private:
|
||||
Vector<StringRef> appInfo;
|
||||
|
||||
CrashEvent crashEvent;
|
||||
|
||||
Vector<MeshTriangle> meshStaging;
|
||||
};
|
||||
|
||||
struct MbpsBlock
|
||||
@@ -406,6 +408,8 @@ private:
|
||||
tracy_force_inline void ProcessCallstackFrame( const QueueCallstackFrame& ev );
|
||||
tracy_force_inline void ProcessCrashReport( const QueueCrashReport& ev );
|
||||
tracy_force_inline void ProcessSysTime( const QueueSysTime& ev );
|
||||
tracy_force_inline void ProcessMeshEnd();
|
||||
tracy_force_inline void ProcessMeshTri( const QueueMeshTri& ev );
|
||||
|
||||
tracy_force_inline void ProcessZoneBeginImpl( ZoneEvent* zone, const QueueZoneBegin& ev );
|
||||
tracy_force_inline void ProcessZoneBeginAllocSrcLocImpl( ZoneEvent* zone, const QueueZoneBegin& ev );
|
||||
|
||||
Reference in New Issue
Block a user