mirror of
https://github.com/wolfpld/tracy.git
synced 2026-06-09 17:13:49 +00:00
Compare commits
7 Commits
v0.5
...
mesh-debug
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d475c3022 | ||
|
|
e7acf05a71 | ||
|
|
41c45e2d2b | ||
|
|
d4db8e2512 | ||
|
|
a25f541297 | ||
|
|
abacf6302b | ||
|
|
5d673eb8f2 |
5
NEWS
5
NEWS
@@ -6,12 +6,9 @@ Note: Release numbers are nothing more than numbers. There are some
|
||||
"missing" versions due to trace file changes during development. This is not
|
||||
a mistake.
|
||||
|
||||
v0.5 (2019-08-10)
|
||||
v0.5 (xxxx-xx-xx)
|
||||
-----------------
|
||||
|
||||
This is the last release which will be able to load pre-v0.4 traces. Use the
|
||||
update utility to convert your old traces now!
|
||||
|
||||
- Major decrease of trace dump file size.
|
||||
- Major optimizations across the board.
|
||||
- Vcpkg is now used for library management on Windows.
|
||||
|
||||
@@ -24,8 +24,7 @@ The following platforms are confirmed to be working (this is not a complete list
|
||||
|
||||
[Introduction to Tracy Profiler v0.2](https://www.youtube.com/watch?v=fB5B46lbapc)
|
||||
[New features in Tracy Profiler v0.3](https://www.youtube.com/watch?v=3SXpDpDh2Uo)
|
||||
[New features in Tracy Profiler v0.4](https://www.youtube.com/watch?v=eAkgkaO8B9o)
|
||||
[New features in Tracy Profiler v0.5](https://www.youtube.com/watch?v=P6E7qLMmzTQ)
|
||||
[New features in Tracy Profiler v0.4](https://www.youtube.com/watch?v=eAkgkaO8B9o)
|
||||
|
||||
[A quick FAQ.](FAQ.md)
|
||||
[List of changes.](NEWS)
|
||||
|
||||
@@ -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
|
||||
@@ -245,35 +245,7 @@ static inline void CpuId( uint32_t* regs, uint32_t leaf )
|
||||
static void InitFailure( const char* msg )
|
||||
{
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
bool hasConsole = false;
|
||||
bool reopen = false;
|
||||
const auto attached = AttachConsole( ATTACH_PARENT_PROCESS );
|
||||
if( attached )
|
||||
{
|
||||
hasConsole = true;
|
||||
reopen = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto err = GetLastError();
|
||||
if( err == ERROR_ACCESS_DENIED )
|
||||
{
|
||||
hasConsole = true;
|
||||
}
|
||||
}
|
||||
if( hasConsole )
|
||||
{
|
||||
fprintf( stderr, "Tracy Profiler initialization failure: %s\n", msg );
|
||||
if( reopen )
|
||||
{
|
||||
freopen( "CONOUT$", "w", stderr );
|
||||
fprintf( stderr, "Tracy Profiler initialization failure: %s\n", msg );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBoxA( nullptr, msg, "Tracy Profiler initialization failure", MB_ICONSTOP );
|
||||
}
|
||||
MessageBoxA( nullptr, msg, "Tracy Profiler initialization failure", MB_ICONSTOP );
|
||||
#else
|
||||
fprintf( stderr, "Tracy Profiler initialization failure: %s\n", msg );
|
||||
#endif
|
||||
@@ -286,14 +258,7 @@ static int64_t SetupHwTimer()
|
||||
CpuId( regs, 0x80000001 );
|
||||
if( !( regs[3] & ( 1 << 27 ) ) ) InitFailure( "CPU doesn't support RDTSCP instruction." );
|
||||
CpuId( regs, 0x80000007 );
|
||||
if( !( regs[3] & ( 1 << 8 ) ) )
|
||||
{
|
||||
const char* noCheck = getenv( "TRACY_NO_INVARIANT_CHECK" );
|
||||
if( !noCheck || noCheck[0] != '1' )
|
||||
{
|
||||
InitFailure( "CPU doesn't support invariant TSC.\nDefine TRACY_NO_INVARIANT_CHECK=1 to ignore this error, *if you know what you are doing*." );
|
||||
}
|
||||
}
|
||||
if( !( regs[3] & ( 1 << 8 ) ) ) InitFailure( "CPU doesn't support invariant TSC." );
|
||||
|
||||
return Profiler::GetTime();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -188,7 +188,7 @@ The Microsoft compiler is very insistent on writing the CPU core identifier to t
|
||||
|
||||
\subsubsection{Misinformation about \texttt{rdtscp}}
|
||||
|
||||
In various internet sources you can find warnings that the \texttt{rdtscp} readings are not reliable, can vary between CPU cores, or can be affected by the CPU frequency adjustments. While this was a sound advice a long time ago, it is no longer valid since the Intel Sandy Bridge microarchitecture (released in 2011) introduced \emph{invariant TSC}. Tracy will check for this feature and refuse to run, if it is not found\footnote{Invariant TSC might be not available in specific scenarios, e.g. in some virtual environments. You may set the environment variable \texttt{TRACY\_NO\_INVARIANT\_CHECK=1} to skip this check, \emph{only if you know what you are doing}.}.
|
||||
In various internet sources you can find warnings that the \texttt{rdtscp} readings are not reliable, can vary between CPU cores, or can be affected by the CPU frequency adjustments. While this was a sound advice a long time ago, it is no longer valid since the Intel Sandy Bridge microarchitecture (released in 2011) introduced \emph{invariant TSC}. Tracy will check for this feature and refuse to run, if it is not found.
|
||||
|
||||
While there could be a timer dispatch function, similar to the one on ARM CPUs, it would incur additional cost, which would be paid by everyone, while benefiting (almost) no one. If need be, an optional macro should be added to enable such dispatch.
|
||||
|
||||
|
||||
@@ -404,10 +404,6 @@ int main( int argc, char** argv )
|
||||
{
|
||||
OpenWebpage( "https://www.youtube.com/watch?v=eAkgkaO8B9o" );
|
||||
}
|
||||
if( ImGui::Selectable( ICON_FA_VIDEO " New features in Tracy Profiler v0.5" ) )
|
||||
{
|
||||
OpenWebpage( "https://www.youtube.com/watch?v=P6E7qLMmzTQ" );
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,8 +6,8 @@ namespace tracy
|
||||
namespace Version
|
||||
{
|
||||
enum { Major = 0 };
|
||||
enum { Minor = 5 };
|
||||
enum { Patch = 0 };
|
||||
enum { Minor = 4 };
|
||||
enum { Patch = 11 };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
@@ -5964,10 +5965,24 @@ void View::DrawMessages()
|
||||
}
|
||||
m_visibleMessages = msgcnt;
|
||||
|
||||
if( ImGui::GetScrollY() >= ImGui::GetScrollMaxY() )
|
||||
if( !filterActive )
|
||||
{
|
||||
ImGui::SetScrollHereY( 1.f );
|
||||
const auto maxScroll = ImGui::GetScrollMaxY();
|
||||
if( maxScroll != 0 )
|
||||
{
|
||||
const auto msgssize = msgs.size();
|
||||
if( m_prevMessages == msgssize && !m_messageFilterWasActive )
|
||||
{
|
||||
m_messagesScrollBottom = ImGui::GetScrollY() == maxScroll;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_prevMessages = msgssize;
|
||||
if( m_messagesScrollBottom ) ImGui::SetScrollHereY();
|
||||
}
|
||||
}
|
||||
}
|
||||
m_messageFilterWasActive = filterActive;
|
||||
|
||||
ImGui::EndColumns();
|
||||
ImGui::EndChild();
|
||||
@@ -9555,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 );
|
||||
@@ -267,7 +268,9 @@ private:
|
||||
ZoneEvent* m_zoneHover = nullptr;
|
||||
int m_frameHover = -1;
|
||||
bool m_messagesScrollBottom;
|
||||
size_t m_prevMessages = 0;
|
||||
ImGuiTextFilter m_messageFilter;
|
||||
bool m_messageFilterWasActive = false;
|
||||
int m_visibleMessages = 0;
|
||||
bool m_disconnectIssued = false;
|
||||
|
||||
@@ -540,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