From fb60fb9928ec9cdb5e2165ccee45222a024e855e Mon Sep 17 00:00:00 2001 From: Hugo Amiard Date: Sat, 30 Jan 2021 14:16:10 +0100 Subject: [PATCH 01/15] Add CMake support --- CMakeLists.txt | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..c933b1ec --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.0) + +project(tracy) + +set(CMAKE_CXX_STANDARD 11) + +option(TRACY_ENABLE "Profiling is enabled" ON) +option(TRACY_ON_DEMAND "Profiling enabled on demand" OFF) +option(TRACY_NO_EXIT "Client executable does not exit until all profile data is sent to server" OFF) +option(TRACY_NO_BROADCAST "Disable client discovery by broadcast to local network" OFF) + +add_library(tracy_client TracyClient.cpp) + +macro(set_option OPTION) + if(${OPTION}) + message(STATUS "${OPTION}: ON") + target_compile_definitions(tracy_client PUBLIC ${OPTION}) + else() + message(STATUS "${OPTION}: OFF") + endif() +endmacro() + +set_option(TRACY_ENABLE) +set_option(TRACY_ON_DEMAND) +set_option(TRACY_NO_EXIT) +set_option(TRACY_NO_BROADCAST) +set_option(TRACY_USE_CONSTEXPR_VARIABLES) + +if(NOT TRACY_PORT) + set(TRACY_PORT 8086) +endif() + +message(STATUS "TRACY_PORT: ${TRACY_PORT}") +target_compile_definitions(tracy_client PUBLIC TRACY_PORT=${TRACY_PORT}) + +target_include_directories(tracy_client PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") \ No newline at end of file From aea72b28ce996223012ce861a63da88d8078dd8f Mon Sep 17 00:00:00 2001 From: Hugo Amiard Date: Fri, 7 Aug 2020 17:09:31 +0200 Subject: [PATCH 02/15] Add SourceLocation macros --- Tracy.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Tracy.hpp b/Tracy.hpp index 8d9ada59..a70497f1 100644 --- a/Tracy.hpp +++ b/Tracy.hpp @@ -105,6 +105,10 @@ #include "client/TracyProfiler.hpp" #include "client/TracyScoped.hpp" +#define TracySourceLocation( varname ) static const tracy::SourceLocationData varname { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; +#define TracySourceLocationN( varname, name ) static const tracy::SourceLocationData varname { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; +#define TracySourceLocationNC( varname, name, color ) static const tracy::SourceLocationData varname { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; + #if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK # define ZoneNamed( varname, active ) static constexpr 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 ); # define ZoneNamedN( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active ); From d44d7db489bfff0efe844433a8b129933b169cd1 Mon Sep 17 00:00:00 2001 From: Hugo Amiard Date: Fri, 7 Aug 2020 17:05:11 +0200 Subject: [PATCH 03/15] Add D3D11 Gpu Context/Zone --- TracyD3D11.hpp | 360 ++++++++++++++++++++++++++++++++++++++++++ common/TracyQueue.hpp | 3 +- 2 files changed, 362 insertions(+), 1 deletion(-) create mode 100644 TracyD3D11.hpp diff --git a/TracyD3D11.hpp b/TracyD3D11.hpp new file mode 100644 index 00000000..94129780 --- /dev/null +++ b/TracyD3D11.hpp @@ -0,0 +1,360 @@ +#ifndef __TRACYD3D11_HPP__ +#define __TRACYD3D11_HPP__ + +// Include this file after you include DirectX 11 headers. + +#if !defined TRACY_ENABLE || !defined _WIN32 + +#define TracyD3D11Context(x,y) +#define TracyD3D11NamedZone(x,y,z) +#define TracyD3D11NamedZoneC(x,y,z,w) +#define TracyD3D11Zone(x,y) +#define TracyD3D11ZoneC(x,y,z) +#define TracyD3D11Collect(x) + +#define TracyD3D11NamedZoneS(x,y,z,w) +#define TracyD3D11NamedZoneCS(x,y,z,w,v) +#define TracyD3D11ZoneS(x,y,z) +#define TracyD3D11ZoneCS(x,y,z,w) + +namespace tracy +{ +class D3D11CtxScope {}; +} + +using TracyD3D11Ctx = void*; + +#else + +#include +#include +#include + +#include "Tracy.hpp" +#include "client/TracyProfiler.hpp" +#include "client/TracyCallstack.hpp" +#include "common/TracyAlign.hpp" +#include "common/TracyAlloc.hpp" + +#define TracyD3D11Context( device, devicectx ) tracy::CreateD3D11Context( physdev, device, queue, cmdbuf, nullptr, nullptr ); +#define TracyD3D11NamedZone( ctx, varname, name, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::Dx11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__) ); +#define TracyD3D11NamedZoneC( ctx, varname, name, color, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::Dx11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__) ); +#define TracyD3D11Zone( ctx, name ) TracyD3D11NamedZone( ctx, ___tracy_gpu_zone, name ) +#define TracyD3D11ZoneC( ctx, name, color ) TracyD3D11NamedZoneC( ctx, ___tracy_gpu_zone, name, color ) +#define TracyD3D11Collect( ctx ) ctx->Collect(); + +#ifdef TRACY_HAS_CALLSTACK +# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::Dx11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth ); +# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::Dx11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth ); +# define TracyD3D11ZoneS( ctx, name, depth ) TracyD3D11NamedZoneS( ctx, ___tracy_gpu_zone, name, depth ) +# define TracyD3D11ZoneCS( ctx, name, color, depth ) TracyD3D11NamedZoneCS( ctx, ___tracy_gpu_zone, name, color, depth ) +#else +# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) TracyD3D11NamedZone( ctx, varname, name ) +# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) TracyD3D11NamedZoneC( ctx, varname, name, color ) +# define TracyD3D11ZoneS( ctx, name, depth, active ) TracyD3D11Zone( ctx, name ) +# define TracyD3D11ZoneCS( ctx, name, color, depth, active ) TracyD3D11ZoneC( name, color ) +#endif + +#define TRACY_D3D11_NO_SINGLE_THREAD + +namespace tracy +{ + +class D3D11Ctx +{ + friend class D3D11CtxScope; + + enum { QueryCount = 64 * 1024 }; + +public: + D3D11Ctx( ID3D11Device* device, ID3D11DeviceContext* devicectx ) + : m_device( device ) + , m_devicectx( devicectx ) + , m_context( GetGpuCtxCounter().fetch_add( 1, std::memory_order_relaxed ) ) + , m_head( 0 ) + , m_tail( 0 ) + { + assert( m_context != 255 ); + + for (int i = 0; i < QueryCount; i++) + { + HRESULT hr = S_OK; + D3D11_QUERY_DESC desc; + desc.MiscFlags = 0; + + desc.Query = D3D11_QUERY_TIMESTAMP; + hr |= device->CreateQuery(&desc, &m_queries[i]); + + desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT; + hr |= device->CreateQuery(&desc, &m_disjoints[i]); + + m_disjointMap[i] = nullptr; + + assert(SUCCEEDED(hr)); + } + + // Force query the initial GPU timestamp (pipeline stall) + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint; + UINT64 timestamp; + for (int attempts = 0; attempts < 50; attempts++) + { + devicectx->Begin(m_disjoints[0]); + devicectx->End(m_queries[0]); + devicectx->End(m_disjoints[0]); + devicectx->Flush(); + + while (devicectx->GetData(m_disjoints[0], &disjoint, sizeof(disjoint), 0) == S_FALSE) + /* Nothing */; + + if (disjoint.Disjoint) + continue; + + while (devicectx->GetData(m_queries[0], ×tamp, sizeof(timestamp), 0) == S_FALSE) + /* Nothing */; + + break; + } + + int64_t tgpu = timestamp * (1000000000ull / disjoint.Frequency); + int64_t tcpu = Profiler::GetTime(); + + uint8_t flags = 0; + + const float period = 1.f; + auto* item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuNewContext ); + MemWrite( &item->gpuNewContext.cpuTime, tcpu ); + MemWrite( &item->gpuNewContext.gpuTime, tgpu ); +#ifdef TRACY_D3D11_NO_SINGLE_THREAD + memset(&item->gpuNewContext.thread, 0, sizeof(item->gpuNewContext.thread)); +#else + MemWrite( &item->gpuNewContext.thread, GetThreadHandle() ); +#endif + MemWrite( &item->gpuNewContext.period, period ); + MemWrite( &item->gpuNewContext.context, m_context ); + MemWrite( &item->gpuNewContext.flags, flags ); + MemWrite( &item->gpuNewContext.type, GpuContextType::Direct3D11 ); + +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + + Profiler::QueueSerialFinish(); + } + + ~D3D11Ctx() + { + for (int i = 0; i < QueryCount; i++) + { + m_queries[i]->Release(); + m_disjoints[i]->Release(); + m_disjointMap[i] = nullptr; + } + } + + void Collect() + { + ZoneScopedC( Color::Red4 ); + + if( m_tail == m_head ) return; + +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) + { + m_head = m_tail = 0; + return; + } +#endif + + auto start = m_tail; + auto end = m_head + QueryCount; + auto cnt = (end - start) % QueryCount; + while (cnt > 1) + { + auto mid = start + cnt / 2; + + bool available = + m_devicectx->GetData(m_disjointMap[mid % QueryCount], nullptr, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH) == S_OK && + m_devicectx->GetData(m_queries[mid % QueryCount], nullptr, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH) == S_OK; + + if (available) + { + start = mid; + } + else + { + end = mid; + } + cnt = (end - start) % QueryCount; + } + + start %= QueryCount; + + while (m_tail != start) + { + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint; + UINT64 time; + + m_devicectx->GetData(m_disjointMap[m_tail], &disjoint, sizeof(disjoint), 0); + m_devicectx->GetData(m_queries[m_tail], &time, sizeof(time), 0); + + time *= (1000000000ull / disjoint.Frequency); + + auto* item = Profiler::QueueSerial(); + MemWrite(&item->hdr.type, QueueType::GpuTime); + MemWrite(&item->gpuTime.gpuTime, (int64_t)time); + MemWrite(&item->gpuTime.queryId, (uint16_t)m_tail); + MemWrite(&item->gpuTime.context, m_context); + Profiler::QueueSerialFinish(); + + m_tail = (m_tail + 1) % QueryCount; + } + } + +private: + tracy_force_inline unsigned int NextQueryId() + { + const auto id = m_head; + m_head = ( m_head + 1 ) % QueryCount; + assert( m_head != m_tail ); + return id; + } + + tracy_force_inline ID3D11Query* TranslateQueryId( unsigned int id ) + { + return m_queries[id]; + } + + tracy_force_inline ID3D11Query* MapDisjointQueryId( unsigned int id, unsigned int disjointId ) + { + m_disjointMap[id] = m_disjoints[disjointId]; + return m_disjoints[disjointId]; + } + + tracy_force_inline uint8_t GetId() const + { + return m_context; + } + + ID3D11Device* m_device; + ID3D11DeviceContext* m_devicectx; + + ID3D11Query* m_queries[QueryCount]; + ID3D11Query* m_disjoints[QueryCount]; + ID3D11Query* m_disjointMap[QueryCount]; // Multiple time queries can have one disjoint query + uint8_t m_context; + + unsigned int m_head; + unsigned int m_tail; +}; + +class D3D11CtxScope +{ +public: + tracy_force_inline D3D11CtxScope( D3D11Ctx* ctx, const SourceLocationData* srcloc, bool is_active ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; + m_ctx = ctx; + + const auto queryId = ctx->NextQueryId(); + ctx->m_devicectx->Begin(ctx->MapDisjointQueryId(queryId, queryId)); + ctx->m_devicectx->End(ctx->TranslateQueryId(queryId)); + + m_disjointId = queryId; + + auto* item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuZoneBeginSerial ); + MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() ); + MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc ); +#ifdef TRACY_D3D11_NO_SINGLE_THREAD + MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() ); +#else + memset(&item->gpuZoneBegin.thread, 0, sizeof(item->gpuNewContext.thread)); +#endif + MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneBegin.context, ctx->GetId() ); + + Profiler::QueueSerialFinish(); + } + + tracy_force_inline D3D11CtxScope( D3D11Ctx* ctx, const SourceLocationData* srcloc, int depth, bool is_active ) +#ifdef TRACY_ON_DEMAND + : m_active( is_active && GetProfiler().IsConnected() ) +#else + : m_active( is_active ) +#endif + { + if( !m_active ) return; + m_ctx = ctx; + + const auto queryId = ctx->NextQueryId(); + ctx->m_devicectx->Begin(ctx->MapDisjointQueryId(queryId, queryId)); + ctx->m_devicectx->End(ctx->TranslateQueryId(queryId)); + + m_disjointId = queryId; + + auto* item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuZoneBeginCallstackSerial ); + MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() ); + MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc ); + MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() ); + MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneBegin.context, ctx->GetId() ); + + Profiler::QueueSerialFinish(); + + GetProfiler().SendCallstack( depth ); + } + + tracy_force_inline ~D3D11CtxScope() + { + if( !m_active ) return; + + const auto queryId = m_ctx->NextQueryId(); + m_ctx->m_devicectx->End(m_ctx->TranslateQueryId(queryId)); + m_ctx->m_devicectx->End(m_ctx->MapDisjointQueryId(queryId, m_disjointId)); + + auto* item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuZoneEndSerial ); + MemWrite( &item->gpuZoneEnd.cpuTime, Profiler::GetTime() ); +#ifdef TRACY_D3D11_NO_SINGLE_THREAD + MemWrite( &item->gpuZoneEnd.thread, GetThreadHandle() ); +#else + memset(&item->gpuZoneEnd.thread, 0, sizeof(item->gpuNewContext.thread)); +#endif + MemWrite( &item->gpuZoneEnd.queryId, uint16_t( queryId ) ); + MemWrite( &item->gpuZoneEnd.context, m_ctx->GetId() ); + + Profiler::QueueSerialFinish(); + } + +private: + const bool m_active; + + D3D11Ctx* m_ctx; + unsigned int m_disjointId; +}; + +static inline D3D11Ctx* CreateD3D11Context( ID3D11Device* device, ID3D11DeviceContext* devicectx ) +{ + InitRPMallocThread(); + auto ctx = (D3D11Ctx*)tracy_malloc( sizeof( D3D11Ctx ) ); + new(ctx) D3D11Ctx( device, devicectx ); + return ctx; +} + +static inline void DestroyD3D11Context( D3D11Ctx* ctx ) +{ + ctx->~D3D11Ctx(); + tracy_free( ctx ); +} +} + +#endif + +#endif diff --git a/common/TracyQueue.hpp b/common/TracyQueue.hpp index 8f933534..a7690ddf 100644 --- a/common/TracyQueue.hpp +++ b/common/TracyQueue.hpp @@ -305,7 +305,8 @@ enum class GpuContextType : uint8_t OpenGl, Vulkan, OpenCL, - Direct3D12 + Direct3D12, + Direct3D11 }; enum GpuContextFlags : uint8_t From 4bf449c4c081599eb2e15aede10d40dabf5c259a Mon Sep 17 00:00:00 2001 From: Hugo Amiard Date: Tue, 9 Feb 2021 11:18:28 +0100 Subject: [PATCH 04/15] Fix Linux build --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c933b1ec..fde4ed4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,4 +33,8 @@ endif() message(STATUS "TRACY_PORT: ${TRACY_PORT}") target_compile_definitions(tracy_client PUBLIC TRACY_PORT=${TRACY_PORT}) -target_include_directories(tracy_client PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") \ No newline at end of file +target_include_directories(tracy_client PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") + +if (UNIX) + target_link_libraries(tracy_client PRIVATE ${CMAKE_DL_LIBS}) +endif() From c5fa9be41e975d33a21cbfe3da83cbb73cf49f86 Mon Sep 17 00:00:00 2001 From: Rahul Gupta Date: Tue, 23 Feb 2021 07:32:03 -0600 Subject: [PATCH 05/15] Fixed the Macro Errors and Renamed Class names for more consistency --- TracyD3D11.hpp | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/TracyD3D11.hpp b/TracyD3D11.hpp index 94129780..d7a06eb9 100644 --- a/TracyD3D11.hpp +++ b/TracyD3D11.hpp @@ -36,25 +36,6 @@ using TracyD3D11Ctx = void*; #include "common/TracyAlign.hpp" #include "common/TracyAlloc.hpp" -#define TracyD3D11Context( device, devicectx ) tracy::CreateD3D11Context( physdev, device, queue, cmdbuf, nullptr, nullptr ); -#define TracyD3D11NamedZone( ctx, varname, name, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::Dx11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__) ); -#define TracyD3D11NamedZoneC( ctx, varname, name, color, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::Dx11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__) ); -#define TracyD3D11Zone( ctx, name ) TracyD3D11NamedZone( ctx, ___tracy_gpu_zone, name ) -#define TracyD3D11ZoneC( ctx, name, color ) TracyD3D11NamedZoneC( ctx, ___tracy_gpu_zone, name, color ) -#define TracyD3D11Collect( ctx ) ctx->Collect(); - -#ifdef TRACY_HAS_CALLSTACK -# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::Dx11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth ); -# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::Dx11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth ); -# define TracyD3D11ZoneS( ctx, name, depth ) TracyD3D11NamedZoneS( ctx, ___tracy_gpu_zone, name, depth ) -# define TracyD3D11ZoneCS( ctx, name, color, depth ) TracyD3D11NamedZoneCS( ctx, ___tracy_gpu_zone, name, color, depth ) -#else -# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) TracyD3D11NamedZone( ctx, varname, name ) -# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) TracyD3D11NamedZoneC( ctx, varname, name, color ) -# define TracyD3D11ZoneS( ctx, name, depth, active ) TracyD3D11Zone( ctx, name ) -# define TracyD3D11ZoneCS( ctx, name, color, depth, active ) TracyD3D11ZoneC( name, color ) -#endif - #define TRACY_D3D11_NO_SINGLE_THREAD namespace tracy @@ -355,6 +336,27 @@ static inline void DestroyD3D11Context( D3D11Ctx* ctx ) } } +using TracyD3D11Ctx = tracy::D3D11Ctx*; + +#define TracyD3D11Context( device, devicectx ) tracy::CreateD3D11Context( device, devicectx ); +#define TracyD3D11NamedZone( ctx, varname, name, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), active ); +#define TracyD3D11NamedZoneC( ctx, varname, name, color, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), active ); +#define TracyD3D11Zone( ctx, name ) TracyD3D11NamedZone( ctx, ___tracy_gpu_zone, name, true ) +#define TracyD3D11ZoneC( ctx, name, color ) TracyD3D11NamedZoneC( ctx, ___tracy_gpu_zone, name, color, true ) +#define TracyD3D11Collect( ctx ) ctx->Collect(); + +#ifdef TRACY_HAS_CALLSTACK +# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth ); +# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth ); +# define TracyD3D11ZoneS( ctx, name, depth ) TracyD3D11NamedZoneS( ctx, ___tracy_gpu_zone, name, depth, true ) +# define TracyD3D11ZoneCS( ctx, name, color, depth ) TracyD3D11NamedZoneCS( ctx, ___tracy_gpu_zone, name, color, depth, true ) +#else +# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) TracyD3D11NamedZone( ctx, varname, name ) +# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) TracyD3D11NamedZoneC( ctx, varname, name, color ) +# define TracyD3D11ZoneS( ctx, name, depth, active ) TracyD3D11Zone( ctx, name ) +# define TracyD3D11ZoneCS( ctx, name, color, depth, active ) TracyD3D11ZoneC( name, color ) +#endif + #endif #endif From a950e444b55f4ce931e52c86e07a70197a8e8510 Mon Sep 17 00:00:00 2001 From: Rahul Gupta Date: Tue, 23 Feb 2021 09:01:06 -0600 Subject: [PATCH 06/15] Updated as suggested by wolf in the PR --- CMakeLists.txt | 4 ---- Tracy.hpp | 4 ---- server/TracyView.cpp | 1 + 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fde4ed4e..d50c70aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,3 @@ message(STATUS "TRACY_PORT: ${TRACY_PORT}") target_compile_definitions(tracy_client PUBLIC TRACY_PORT=${TRACY_PORT}) target_include_directories(tracy_client PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") - -if (UNIX) - target_link_libraries(tracy_client PRIVATE ${CMAKE_DL_LIBS}) -endif() diff --git a/Tracy.hpp b/Tracy.hpp index a70497f1..8d9ada59 100644 --- a/Tracy.hpp +++ b/Tracy.hpp @@ -105,10 +105,6 @@ #include "client/TracyProfiler.hpp" #include "client/TracyScoped.hpp" -#define TracySourceLocation( varname ) static const tracy::SourceLocationData varname { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; -#define TracySourceLocationN( varname, name ) static const tracy::SourceLocationData varname { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; -#define TracySourceLocationNC( varname, name, color ) static const tracy::SourceLocationData varname { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; - #if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK # define ZoneNamed( varname, active ) static constexpr 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 ); # define ZoneNamedN( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active ); diff --git a/server/TracyView.cpp b/server/TracyView.cpp index 4d5ba128..945c1041 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -72,6 +72,7 @@ constexpr const char* GpuContextNames[] = { "Vulkan", "OpenCL", "Direct3D 12" + "Direct3D 11" }; From e9fd767884e0e03447cc0901d573766a5222efe4 Mon Sep 17 00:00:00 2001 From: David Farrell Date: Sat, 1 May 2021 15:03:02 -0700 Subject: [PATCH 07/15] Added missing comma in GpuContextNames --- server/TracyView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/TracyView.cpp b/server/TracyView.cpp index 945c1041..2d71bc5e 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -71,7 +71,7 @@ constexpr const char* GpuContextNames[] = { "OpenGL", "Vulkan", "OpenCL", - "Direct3D 12" + "Direct3D 12", "Direct3D 11" }; From 9546ff18b843bedac8aec28decefb6230ccbedd7 Mon Sep 17 00:00:00 2001 From: David Farrell Date: Sat, 1 May 2021 15:03:53 -0700 Subject: [PATCH 08/15] Removed CMakeLists.txt --- CMakeLists.txt | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index d50c70aa..00000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -cmake_minimum_required(VERSION 3.0) - -project(tracy) - -set(CMAKE_CXX_STANDARD 11) - -option(TRACY_ENABLE "Profiling is enabled" ON) -option(TRACY_ON_DEMAND "Profiling enabled on demand" OFF) -option(TRACY_NO_EXIT "Client executable does not exit until all profile data is sent to server" OFF) -option(TRACY_NO_BROADCAST "Disable client discovery by broadcast to local network" OFF) - -add_library(tracy_client TracyClient.cpp) - -macro(set_option OPTION) - if(${OPTION}) - message(STATUS "${OPTION}: ON") - target_compile_definitions(tracy_client PUBLIC ${OPTION}) - else() - message(STATUS "${OPTION}: OFF") - endif() -endmacro() - -set_option(TRACY_ENABLE) -set_option(TRACY_ON_DEMAND) -set_option(TRACY_NO_EXIT) -set_option(TRACY_NO_BROADCAST) -set_option(TRACY_USE_CONSTEXPR_VARIABLES) - -if(NOT TRACY_PORT) - set(TRACY_PORT 8086) -endif() - -message(STATUS "TRACY_PORT: ${TRACY_PORT}") -target_compile_definitions(tracy_client PUBLIC TRACY_PORT=${TRACY_PORT}) - -target_include_directories(tracy_client PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") From 76294ca458a4b33be822ee915cc6698dc5a0eb44 Mon Sep 17 00:00:00 2001 From: David Farrell Date: Sat, 1 May 2021 15:43:53 -0700 Subject: [PATCH 09/15] This commit makes the D3D11 code consistent with the D3D12 code. It now properly supports TRACY_CALLSTACK as well as the Tracy*Transient macros. The order of the macros now has the same order as the D3D12 file. Added support for TracyD3D11ContextName(). I removed TRACY_D3D11_NO_SINGLE_THREAD, because I'm not sure what that is supposed to be used for. It was set up in an upstream fork of Tracy. --- TracyD3D11.hpp | 163 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 122 insertions(+), 41 deletions(-) diff --git a/TracyD3D11.hpp b/TracyD3D11.hpp index d7a06eb9..712e1a17 100644 --- a/TracyD3D11.hpp +++ b/TracyD3D11.hpp @@ -1,25 +1,31 @@ #ifndef __TRACYD3D11_HPP__ #define __TRACYD3D11_HPP__ -// Include this file after you include DirectX 11 headers. +#ifndef TRACY_ENABLE -#if !defined TRACY_ENABLE || !defined _WIN32 +#define TracyD3D11Context(device,queue) nullptr +#define TracyD3D11Destroy(ctx) +#define TracyD3D11ContextName(ctx, name, size) -#define TracyD3D11Context(x,y) -#define TracyD3D11NamedZone(x,y,z) -#define TracyD3D11NamedZoneC(x,y,z,w) -#define TracyD3D11Zone(x,y) -#define TracyD3D11ZoneC(x,y,z) -#define TracyD3D11Collect(x) +#define TracyD3D11NewFrame(ctx) -#define TracyD3D11NamedZoneS(x,y,z,w) -#define TracyD3D11NamedZoneCS(x,y,z,w,v) -#define TracyD3D11ZoneS(x,y,z) -#define TracyD3D11ZoneCS(x,y,z,w) +#define TracyD3D11Zone(ctx, name) +#define TracyD3D11ZoneC(ctx, name, color) +#define TracyD3D11NamedZone(ctx, varname, name, active) +#define TracyD3D11NamedZoneC(ctx, varname, name, color, active) +#define TracyD3D12ZoneTransient(ctx, varname, name, active) + +#define TracyD3D11ZoneS(ctx, name, depth) +#define TracyD3D11ZoneCS(ctx, name, color, depth) +#define TracyD3D11NamedZoneS(ctx, varname, name, depth, active) +#define TracyD3D11NamedZoneCS(ctx, varname, name, color, depth, active) +#define TracyD3D12ZoneTransientS(ctx, varname, name, depth, active) + +#define TracyD3D11Collect(ctx) namespace tracy { -class D3D11CtxScope {}; +class D3D11ZoneScope {}; } using TracyD3D11Ctx = void*; @@ -36,14 +42,12 @@ using TracyD3D11Ctx = void*; #include "common/TracyAlign.hpp" #include "common/TracyAlloc.hpp" -#define TRACY_D3D11_NO_SINGLE_THREAD - namespace tracy { class D3D11Ctx { - friend class D3D11CtxScope; + friend class D3D11ZoneScope; enum { QueryCount = 64 * 1024 }; @@ -106,11 +110,7 @@ public: MemWrite( &item->hdr.type, QueueType::GpuNewContext ); MemWrite( &item->gpuNewContext.cpuTime, tcpu ); MemWrite( &item->gpuNewContext.gpuTime, tgpu ); -#ifdef TRACY_D3D11_NO_SINGLE_THREAD memset(&item->gpuNewContext.thread, 0, sizeof(item->gpuNewContext.thread)); -#else - MemWrite( &item->gpuNewContext.thread, GetThreadHandle() ); -#endif MemWrite( &item->gpuNewContext.period, period ); MemWrite( &item->gpuNewContext.context, m_context ); MemWrite( &item->gpuNewContext.flags, flags ); @@ -133,6 +133,22 @@ public: } } + void Name( const char* name, uint16_t len ) + { + auto ptr = (char*)tracy_malloc( len ); + memcpy( ptr, name, len ); + + auto item = Profiler::QueueSerial(); + MemWrite( &item->hdr.type, QueueType::GpuContextName ); + MemWrite( &item->gpuContextNameFat.context, m_context ); + MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr ); + MemWrite( &item->gpuContextNameFat.size, len ); +#ifdef TRACY_ON_DEMAND + GetProfiler().DeferItem( *item ); +#endif + Profiler::QueueSerialFinish(); + } + void Collect() { ZoneScopedC( Color::Red4 ); @@ -229,10 +245,10 @@ private: unsigned int m_tail; }; -class D3D11CtxScope +class D3D11ZoneScope { public: - tracy_force_inline D3D11CtxScope( D3D11Ctx* ctx, const SourceLocationData* srcloc, bool is_active ) + tracy_force_inline D3D11ZoneScope( D3D11Ctx* ctx, const SourceLocationData* srcloc, bool is_active ) #ifdef TRACY_ON_DEMAND : m_active( is_active && GetProfiler().IsConnected() ) #else @@ -252,18 +268,14 @@ public: MemWrite( &item->hdr.type, QueueType::GpuZoneBeginSerial ); MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() ); MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc ); -#ifdef TRACY_D3D11_NO_SINGLE_THREAD MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() ); -#else - memset(&item->gpuZoneBegin.thread, 0, sizeof(item->gpuNewContext.thread)); -#endif MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) ); MemWrite( &item->gpuZoneBegin.context, ctx->GetId() ); Profiler::QueueSerialFinish(); } - tracy_force_inline D3D11CtxScope( D3D11Ctx* ctx, const SourceLocationData* srcloc, int depth, bool is_active ) + tracy_force_inline D3D11ZoneScope( D3D11Ctx* ctx, const SourceLocationData* srcloc, int depth, bool is_active ) #ifdef TRACY_ON_DEMAND : m_active( is_active && GetProfiler().IsConnected() ) #else @@ -292,7 +304,65 @@ public: GetProfiler().SendCallstack( depth ); } - tracy_force_inline ~D3D11CtxScope() + tracy_force_inline D3D11ZoneScope(D3D11Ctx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool active) +#ifdef TRACY_ON_DEMAND + : m_active(active&& GetProfiler().IsConnected()) +#else + : m_active(active) +#endif + { + if( !m_active ) return; + m_ctx = ctx; + + const auto queryId = ctx->NextQueryId(); + ctx->m_devicectx->Begin(ctx->MapDisjointQueryId(queryId, queryId)); + ctx->m_devicectx->End(ctx->TranslateQueryId(queryId)); + + m_disjointId = queryId; + + const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz); + + auto* item = Profiler::QueueSerial(); + MemWrite(&item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocSerial); + MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime()); + MemWrite(&item->gpuZoneBegin.srcloc, sourceLocation); + MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle()); + MemWrite(&item->gpuZoneBegin.queryId, static_cast(queryId)); + MemWrite(&item->gpuZoneBegin.context, ctx->GetId()); + + Profiler::QueueSerialFinish(); + } + + tracy_force_inline D3D11ZoneScope(D3D11Ctx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int depth, bool active) +#ifdef TRACY_ON_DEMAND + : m_active(active&& GetProfiler().IsConnected()) +#else + : m_active(active) +#endif + { + if( !m_active ) return; + m_ctx = ctx; + + const auto queryId = ctx->NextQueryId(); + ctx->m_devicectx->Begin(ctx->MapDisjointQueryId(queryId, queryId)); + ctx->m_devicectx->End(ctx->TranslateQueryId(queryId)); + + m_disjointId = queryId; + + const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz); + + auto* item = Profiler::QueueSerialCallstack(Callstack(depth)); + MemWrite(&item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial); + MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime()); + MemWrite(&item->gpuZoneBegin.srcloc, sourceLocation); + MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle()); + MemWrite(&item->gpuZoneBegin.queryId, static_cast(queryId)); + MemWrite(&item->gpuZoneBegin.context, ctx->GetId()); + + Profiler::QueueSerialFinish(); + } + + tracy_force_inline ~D3D11ZoneScope() { if( !m_active ) return; @@ -303,11 +373,7 @@ public: auto* item = Profiler::QueueSerial(); MemWrite( &item->hdr.type, QueueType::GpuZoneEndSerial ); MemWrite( &item->gpuZoneEnd.cpuTime, Profiler::GetTime() ); -#ifdef TRACY_D3D11_NO_SINGLE_THREAD MemWrite( &item->gpuZoneEnd.thread, GetThreadHandle() ); -#else - memset(&item->gpuZoneEnd.thread, 0, sizeof(item->gpuNewContext.thread)); -#endif MemWrite( &item->gpuZoneEnd.queryId, uint16_t( queryId ) ); MemWrite( &item->gpuZoneEnd.context, m_ctx->GetId() ); @@ -339,24 +405,39 @@ static inline void DestroyD3D11Context( D3D11Ctx* ctx ) using TracyD3D11Ctx = tracy::D3D11Ctx*; #define TracyD3D11Context( device, devicectx ) tracy::CreateD3D11Context( device, devicectx ); -#define TracyD3D11NamedZone( ctx, varname, name, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), active ); -#define TracyD3D11NamedZoneC( ctx, varname, name, color, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), active ); -#define TracyD3D11Zone( ctx, name ) TracyD3D11NamedZone( ctx, ___tracy_gpu_zone, name, true ) -#define TracyD3D11ZoneC( ctx, name, color ) TracyD3D11NamedZoneC( ctx, ___tracy_gpu_zone, name, color, true ) -#define TracyD3D11Collect( ctx ) ctx->Collect(); +#define TracyD3D11Destroy(ctx) tracy::DestroyD3D11Context(ctx); +#define TracyD3D11ContextName(ctx, name, size) ctx->Name(name, size); + +#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK +# define TracyD3D11Zone( ctx, name ) TracyD3D11NamedZoneS( ctx, ___tracy_gpu_zone, name, TRACY_CALLSTACK, true ) +# define TracyD3D11ZoneC( ctx, name, color ) TracyD3D11NamedZoneCS( ctx, ___tracy_gpu_zone, name, color, TRACY_CALLSTACK, true ) +# define TracyD3D11NamedZone( ctx, varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D11ZoneScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), TRACY_CALLSTACK, active ); +# define TracyD3D11NamedZoneC( ctx, varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D11ZoneScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), TRACY_CALLSTACK, active ); +# define TracyD3D11ZoneTransient(ctx, varname, name, active) TracyD3D11ZoneTransientS(ctx, varname, cmdList, name, TRACY_CALLSTACK, active) +#else +# define TracyD3D11Zone( ctx, name ) TracyD3D11NamedZone( ctx, ___tracy_gpu_zone, name, true ) +# define TracyD3D11ZoneC( ctx, name, color ) TracyD3D11NamedZoneC( ctx, ___tracy_gpu_zone, name, color, true ) +# define TracyD3D11NamedZone( ctx, varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D11ZoneScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), active ); +# define TracyD3D11NamedZoneC( ctx, varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D11ZoneScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), active ); +# define TracyD3D11ZoneTransient(ctx, varname, name, active) tracy::D3D11ZoneScope varname{ ctx, __LINE__, __FILE__, strlen(__FILE__), __FUNCTION__, strlen(__FUNCTION__), name, strlen(name), active }; +#endif #ifdef TRACY_HAS_CALLSTACK -# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth ); -# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) static const tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D11CtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth ); # define TracyD3D11ZoneS( ctx, name, depth ) TracyD3D11NamedZoneS( ctx, ___tracy_gpu_zone, name, depth, true ) # define TracyD3D11ZoneCS( ctx, name, color, depth ) TracyD3D11NamedZoneCS( ctx, ___tracy_gpu_zone, name, color, depth, true ) +# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D11ZoneScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth, active ); +# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D11ZoneScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth, active ); +# define TracyD3D11ZoneTransientS(ctx, varname, name, depth, active) tracy::D3D11ZoneScope varname{ ctx, __LINE__, __FILE__, strlen(__FILE__), __FUNCTION__, strlen(__FUNCTION__), name, strlen(name), depth, active }; #else -# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) TracyD3D11NamedZone( ctx, varname, name ) -# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) TracyD3D11NamedZoneC( ctx, varname, name, color ) # define TracyD3D11ZoneS( ctx, name, depth, active ) TracyD3D11Zone( ctx, name ) # define TracyD3D11ZoneCS( ctx, name, color, depth, active ) TracyD3D11ZoneC( name, color ) +# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) TracyD3D11NamedZone( ctx, varname, name, active ) +# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) TracyD3D11NamedZoneC( ctx, varname, name, color, active ) +# define TracyD3D11ZoneTransientS(ctx, varname, name, depth, active) TracyD3D12ZoneTransient(ctx, varname, name, active) #endif +#define TracyD3D11Collect( ctx ) ctx->Collect(); + #endif #endif From dcf33b51cf47ef0858cbb3bc7cce5cca8da41089 Mon Sep 17 00:00:00 2001 From: David Farrell Date: Sat, 1 May 2021 15:55:49 -0700 Subject: [PATCH 10/15] Updated comment to say that both OpenGL _and_ Direct3D11 don't need per-zone thread id. --- server/TracyWorker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index 849bca68..9c613dfc 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -5353,7 +5353,7 @@ void Worker::ProcessGpuZoneBeginImplCommon( GpuEvent* zone, const QueueGpuZoneBe } else { - // OpenGL doesn't need per-zone thread id. It still can be sent, + // OpenGL and Direct3D11 doesn't need per-zone thread id. It still can be sent, // because it may be needed for callstack collection purposes. zone->SetThread( 0 ); ztid = 0; From fe2adc8df460ed796b0bb54f07599076ab0ccb13 Mon Sep 17 00:00:00 2001 From: David Farrell Date: Sat, 1 May 2021 15:56:39 -0700 Subject: [PATCH 11/15] Updated authors --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index b91591c7..347c3c8e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -13,3 +13,4 @@ Simonas Kazlauskas (OSX CI, external bindings) Jakub Žádník (csvexport utility) Andrey Voroshilov (multi-DLL fixes) Benoit Jacob (Android improvements) +David Farrel (Direct3D 11 support) From 3ad3d0234f51bf907a4f312dad2e8f6ac6e149ed Mon Sep 17 00:00:00 2001 From: David Farrell Date: Sat, 1 May 2021 16:54:59 -0700 Subject: [PATCH 12/15] Updated documentation with D3D11 information. --- manual/tracy.tex | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/manual/tracy.tex b/manual/tracy.tex index 550b3b7e..aa8b0d08 100644 --- a/manual/tracy.tex +++ b/manual/tracy.tex @@ -137,7 +137,9 @@ There's much more Tracy can do, which can be explored by carefully reading this \section{A quick look at Tracy Profiler} \label{quicklook} -Tracy is a real-time, nanosecond resolution \emph{hybrid frame and sampling profiler} that can be used for remote or embedded telemetry of games and other applications. It can profile CPU (C, C++11, Lua), GPU (OpenGL, Vulkan, Direct3D 12, OpenCL) and memory. It also can monitor locks held by threads and show where contention does happen. +Tracy is a real-time, nanosecond resolution \emph{hybrid frame and sampling profiler} that can be used for remote or +embedded telemetry of games and other applications. It can profile CPU (C, C++11, Lua), GPU (OpenGL, Vulkan, Direct3D +11/12, OpenCL) and memory. It also can monitor locks held by threads and show where contention does happen. While Tracy can perform statistical analysis of sampled call stack data, just like other \emph{statistical profilers} (such as VTune, perf or Very Sleepy), it mainly focuses on manual markup of the source code, which allows frame-by-frame inspection of the program execution. You will be able to see exactly which functions are called, how much time is spent in them, and how do they interact with each other in a multi-threaded environment. In contrast, the statistical analysis may show you the hot spots in your code, but it is unable to accurately pinpoint the underlying cause for semi-random frame stutter that may occur every couple of seconds. @@ -1314,7 +1316,7 @@ To mark that a separate memory pool is to be tracked you should use the named ve \subsection{GPU profiling} \label{gpuprofiling} -Tracy provides bindings for profiling OpenGL, Vulkan, Direct3D 12 and OpenCL execution time on GPU. +Tracy provides bindings for profiling OpenGL, Vulkan, Direct3D 11, Direct3D 12 and OpenCL execution time on GPU. Note that the CPU and GPU timers may be not synchronized, unless a calibrated context is created. Since availability of calibrated contexts is limited, you can correct the desynchronization of uncalibrated contexts in the profiler's options (section~\ref{options}). @@ -1373,6 +1375,14 @@ In order to maintain synchronization between CPU and GPU time domains, you will To enable calibrated context, replace the macro \texttt{TracyVkContext} with \texttt{TracyVkContextCalibrated} and pass the two functions as additional parameters, in the order specified above. +\subsubsection{Direct3D11} + +To enable Direct3D 11 support, include the \texttt{tracy/TracyD3D11.hpp} header file, and create a \texttt{TracyD3D11Ctx} object with the \texttt{TracyD3D11Context(device, devicecontext)} macro. The object should later be cleaned up with the \texttt{TracyD3D11Destroy} macro. Tracy does not support D3D11 command lists. To set a custom name for the context, use the \texttt{TracyGpuContextName(name, size)} macro. + +To mark a GPU zone, use the \texttt{TracyD3D11Zone(name)} macro, where \texttt{name} is a string literal name of the zone. Alternatively you may use \texttt{TracyD3D11ZoneC(name, color)} to specify zone color. + +You also need to periodically collect the GPU events using the \texttt{TracyD3D11Collect} macro. A good place to do it is after the swap chain present function. + \subsubsection{Direct3D 12} To enable Direct3D 12 support, include the \texttt{tracy/TracyD3D12.hpp} header file. Tracing Direct3D 12 queues is nearly on par with the Vulkan implementation, where a \texttt{TracyD3D12Ctx} is returned from a call to \texttt{TracyD3D12Context(device, queue)}, which should be later cleaned up with the \texttt{TracyD3D12Destroy(ctx)} macro. Multiple contexts can be created, each with any queue type. To set a custom name for the context, use the \texttt{TracyD3D12ContextName(ctx, name, size)} macro. @@ -1401,13 +1411,13 @@ Similarly to Vulkan and OpenGL, you also need to periodically collect the OpenCL Putting more than one GPU zone macro in a single scope features the same issue as with the \texttt{ZoneScoped} macros, described in section~\ref{multizone} (but this time the variable name is \texttt{\_\_\_tracy\_gpu\_zone}). -To solve this problem, in case of OpenGL use the \texttt{TracyGpuNamedZone} macro in place of \texttt{TracyGpuZone} (or the color variant). The same applies to Vulkan and Direct3D 12 -- replace \texttt{TracyVkZone} with \texttt{TracyVkNamedZone} and \texttt{TracyD3D12Zone} with \texttt{TracyD3D12NamedZone}. +To solve this problem, in case of OpenGL use the \texttt{TracyGpuNamedZone} macro in place of \texttt{TracyGpuZone} (or the color variant). The same applies to Vulkan and Direct3D 11/12 -- replace \texttt{TracyVkZone} with \texttt{TracyVkNamedZone} and \texttt{TracyD3D11Zone}/\texttt{TracyD3D12Zone} with \texttt{TracyD3D11NamedZone}/\texttt{TracyD3D12NamedZone}. Remember that you need to provide your own name for the created stack variable as the first parameter to the macros. \subsubsection{Transient GPU zones} -Transient zones (see section~\ref{transientzones} for details) are available in OpenGL, Vulkan, and Direct3D 12 macros. +Transient zones (see section~\ref{transientzones} for details) are available in OpenGL, Vulkan, and Direct3D 11/12 macros. \subsection{Collecting call stacks} \label{collectingcallstacks} From 23010ee4d0bee158ae9a767fca2de904134578f2 Mon Sep 17 00:00:00 2001 From: David Farrell Date: Sat, 1 May 2021 16:56:52 -0700 Subject: [PATCH 13/15] Updated README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 29aa1168..0cbea1b0 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ### A real time, nanosecond resolution, remote telemetry, hybrid frame and sampling profiler for games and other applications. -Tracy supports profiling CPU (C, C++11, Lua), GPU (OpenGL, Vulkan, OpenCL, Direct3D 12), memory, locks, context switches, per-frame screenshots and more. +Tracy supports profiling CPU (C, C++11, Lua), GPU (OpenGL, Vulkan, OpenCL, Direct3D 11/12), memory, locks, context switches, per-frame screenshots and more. For usage **and build process** instructions, consult the user manual [at the following address](https://github.com/wolfpld/tracy/releases). From c668a085306ac81044e1003c51016497f71f6180 Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Sun, 2 May 2021 02:21:49 +0200 Subject: [PATCH 14/15] Missing space. --- manual/tracy.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manual/tracy.tex b/manual/tracy.tex index aa8b0d08..f010a81d 100644 --- a/manual/tracy.tex +++ b/manual/tracy.tex @@ -1375,7 +1375,7 @@ In order to maintain synchronization between CPU and GPU time domains, you will To enable calibrated context, replace the macro \texttt{TracyVkContext} with \texttt{TracyVkContextCalibrated} and pass the two functions as additional parameters, in the order specified above. -\subsubsection{Direct3D11} +\subsubsection{Direct3D 11} To enable Direct3D 11 support, include the \texttt{tracy/TracyD3D11.hpp} header file, and create a \texttt{TracyD3D11Ctx} object with the \texttt{TracyD3D11Context(device, devicecontext)} macro. The object should later be cleaned up with the \texttt{TracyD3D11Destroy} macro. Tracy does not support D3D11 command lists. To set a custom name for the context, use the \texttt{TracyGpuContextName(name, size)} macro. From 3f2d0bbf6ec6a495e059c62aaee8a190ef7ea0d4 Mon Sep 17 00:00:00 2001 From: David Farrell Date: Sat, 1 May 2021 17:29:27 -0700 Subject: [PATCH 15/15] The ToyPathTracer example uses the D3D11 GPU zones --- examples/ToyPathTracer/Windows/TestWin.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/ToyPathTracer/Windows/TestWin.cpp b/examples/ToyPathTracer/Windows/TestWin.cpp index 7acc8595..c6796b90 100644 --- a/examples/ToyPathTracer/Windows/TestWin.cpp +++ b/examples/ToyPathTracer/Windows/TestWin.cpp @@ -16,6 +16,7 @@ #include "CompiledPixelShader.h" #include "../../../Tracy.hpp" +#include "../../../TracyD3D11.hpp" static HINSTANCE g_HInstance; static HWND g_Wnd; @@ -44,6 +45,7 @@ static ID3D11UnorderedAccessView *g_BackbufferUAV, *g_BackbufferUAV2; static ID3D11SamplerState* g_SamplerLinear; static ID3D11RasterizerState* g_RasterState; static int g_BackbufferIndex; +static tracy::D3D11Ctx *g_tracyCtx; #if DO_COMPUTE_GPU @@ -215,6 +217,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE, _In_ LPWSTR, else { RenderFrame(); + TracyD3D11Collect(g_tracyCtx); if( --framesLeft == 0 ) break; } } @@ -271,6 +274,7 @@ static int s_FrameCount = 0; static void RenderFrame() { ZoneScoped; + TracyD3D11Zone(g_tracyCtx, "RenderFrame"); LARGE_INTEGER time1; @@ -541,6 +545,10 @@ static HRESULT InitD3DDevice() vp.TopLeftY = 0; g_D3D11Ctx->RSSetViewports(1, &vp); + g_tracyCtx = TracyD3D11Context(g_D3D11Device, g_D3D11Ctx); + const char* tracyD3D11CtxName = "D3D11"; + TracyD3D11ContextName(g_tracyCtx, tracyD3D11CtxName, (uint16_t)strlen(tracyD3D11CtxName)); + return S_OK; } @@ -548,6 +556,8 @@ static void ShutdownD3DDevice() { ZoneScoped; + if (g_tracyCtx) TracyD3D11Destroy(g_tracyCtx); + if (g_D3D11Ctx) g_D3D11Ctx->ClearState(); if (g_D3D11RenderTarget) g_D3D11RenderTarget->Release();