Compare commits

...

7 Commits

Author SHA1 Message Date
Bartosz Taudul
7d475c3022 Reverse drawing order. 2019-08-06 17:08:54 +02:00
Bartosz Taudul
e7acf05a71 Better layout. 2019-08-06 16:29:01 +02:00
Bartosz Taudul
41c45e2d2b Draw mesh debug. 2019-08-06 16:20:40 +02:00
Bartosz Taudul
d4db8e2512 Save/load mesh data. 2019-08-06 11:44:05 +02:00
Bartosz Taudul
a25f541297 Associate mesh data with frames. 2019-08-05 16:58:20 +02:00
Bartosz Taudul
abacf6302b Push mesh triangles into staging vector. 2019-08-05 16:49:45 +02:00
Bartosz Taudul
5d673eb8f2 Add 2D mesh debug interface. 2019-08-05 16:47:20 +02:00
9 changed files with 300 additions and 1 deletions

View File

@@ -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
View 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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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 )
{

View File

@@ -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;
};
}

View File

@@ -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

View File

@@ -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 );