TracyD3D12.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. #ifndef __TRACYD3D12_HPP__
  2. #define __TRACYD3D12_HPP__
  3. #ifndef TRACY_ENABLE
  4. #define TracyD3D12Context(device, queue) nullptr
  5. #define TracyD3D12Destroy(ctx)
  6. #define TracyD3D12ContextName(ctx, name, size)
  7. #define TracyD3D12NewFrame(ctx)
  8. #define TracyD3D12Zone(ctx, cmdList, name)
  9. #define TracyD3D12ZoneC(ctx, cmdList, name, color)
  10. #define TracyD3D12NamedZone(ctx, varname, cmdList, name, active)
  11. #define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active)
  12. #define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active)
  13. #define TracyD3D12ZoneS(ctx, cmdList, name, depth)
  14. #define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth)
  15. #define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active)
  16. #define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active)
  17. #define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active)
  18. #define TracyD3D12Collect(ctx)
  19. namespace tracy
  20. {
  21. class D3D12ZoneScope {};
  22. }
  23. using TracyD3D12Ctx = void*;
  24. #else
  25. #include "Tracy.hpp"
  26. #include "client/TracyProfiler.hpp"
  27. #include "client/TracyCallstack.hpp"
  28. #include <cstdlib>
  29. #include <cassert>
  30. #include <d3d12.h>
  31. #include <dxgi.h>
  32. #include <wrl/client.h>
  33. #include <queue>
  34. namespace tracy
  35. {
  36. struct D3D12QueryPayload
  37. {
  38. uint32_t m_queryIdStart = 0;
  39. uint32_t m_queryCount = 0;
  40. };
  41. // Command queue context.
  42. class D3D12QueueCtx
  43. {
  44. friend class D3D12ZoneScope;
  45. static constexpr uint32_t MaxQueries = 64 * 1024; // Queries are begin and end markers, so we can store half as many total time durations. Must be even!
  46. bool m_initialized = false;
  47. ID3D12Device* m_device = nullptr;
  48. ID3D12CommandQueue* m_queue = nullptr;
  49. uint8_t m_context;
  50. Microsoft::WRL::ComPtr<ID3D12QueryHeap> m_queryHeap;
  51. Microsoft::WRL::ComPtr<ID3D12Resource> m_readbackBuffer;
  52. // In-progress payload.
  53. uint32_t m_queryLimit = MaxQueries;
  54. uint32_t m_queryCounter = 0;
  55. uint32_t m_previousQueryCounter = 0;
  56. uint32_t m_activePayload = 0;
  57. Microsoft::WRL::ComPtr<ID3D12Fence> m_payloadFence;
  58. std::queue<D3D12QueryPayload> m_payloadQueue;
  59. int64_t m_prevCalibration = 0;
  60. int64_t m_qpcToNs = int64_t{ 1000000000 / GetFrequencyQpc() };
  61. public:
  62. D3D12QueueCtx(ID3D12Device* device, ID3D12CommandQueue* queue)
  63. : m_device(device)
  64. , m_queue(queue)
  65. , m_context(GetGpuCtxCounter().fetch_add(1, std::memory_order_relaxed))
  66. {
  67. // Verify we support timestamp queries on this queue.
  68. if (queue->GetDesc().Type == D3D12_COMMAND_LIST_TYPE_COPY)
  69. {
  70. D3D12_FEATURE_DATA_D3D12_OPTIONS3 featureData{};
  71. if (FAILED(device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, &featureData, sizeof(featureData))))
  72. {
  73. assert(false && "Platform does not support profiling of copy queues.");
  74. }
  75. }
  76. uint64_t timestampFrequency;
  77. if (FAILED(queue->GetTimestampFrequency(&timestampFrequency)))
  78. {
  79. assert(false && "Failed to get timestamp frequency.");
  80. }
  81. uint64_t cpuTimestamp;
  82. uint64_t gpuTimestamp;
  83. if (FAILED(queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp)))
  84. {
  85. assert(false && "Failed to get queue clock calibration.");
  86. }
  87. // Save the device cpu timestamp, not the profiler's timestamp.
  88. m_prevCalibration = cpuTimestamp * m_qpcToNs;
  89. cpuTimestamp = Profiler::GetTime();
  90. D3D12_QUERY_HEAP_DESC heapDesc{};
  91. heapDesc.Type = queue->GetDesc().Type == D3D12_COMMAND_LIST_TYPE_COPY ? D3D12_QUERY_HEAP_TYPE_COPY_QUEUE_TIMESTAMP : D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
  92. heapDesc.Count = m_queryLimit;
  93. heapDesc.NodeMask = 0; // #TODO: Support multiple adapters.
  94. while (FAILED(device->CreateQueryHeap(&heapDesc, IID_PPV_ARGS(&m_queryHeap))))
  95. {
  96. m_queryLimit /= 2;
  97. heapDesc.Count = m_queryLimit;
  98. }
  99. // Create a readback buffer, which will be used as a destination for the query data.
  100. D3D12_RESOURCE_DESC readbackBufferDesc{};
  101. readbackBufferDesc.Alignment = 0;
  102. readbackBufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
  103. readbackBufferDesc.Width = m_queryLimit * sizeof(uint64_t);
  104. readbackBufferDesc.Height = 1;
  105. readbackBufferDesc.DepthOrArraySize = 1;
  106. readbackBufferDesc.Format = DXGI_FORMAT_UNKNOWN;
  107. readbackBufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; // Buffers are always row major.
  108. readbackBufferDesc.MipLevels = 1;
  109. readbackBufferDesc.SampleDesc.Count = 1;
  110. readbackBufferDesc.SampleDesc.Quality = 0;
  111. readbackBufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
  112. D3D12_HEAP_PROPERTIES readbackHeapProps{};
  113. readbackHeapProps.Type = D3D12_HEAP_TYPE_READBACK;
  114. readbackHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
  115. readbackHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
  116. readbackHeapProps.CreationNodeMask = 0;
  117. readbackHeapProps.VisibleNodeMask = 0; // #TODO: Support multiple adapters.
  118. if (FAILED(device->CreateCommittedResource(&readbackHeapProps, D3D12_HEAP_FLAG_NONE, &readbackBufferDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_readbackBuffer))))
  119. {
  120. assert(false && "Failed to create query readback buffer.");
  121. }
  122. if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_payloadFence))))
  123. {
  124. assert(false && "Failed to create payload fence.");
  125. }
  126. auto* item = Profiler::QueueSerial();
  127. MemWrite(&item->hdr.type, QueueType::GpuNewContext);
  128. MemWrite(&item->gpuNewContext.cpuTime, cpuTimestamp);
  129. MemWrite(&item->gpuNewContext.gpuTime, gpuTimestamp);
  130. memset(&item->gpuNewContext.thread, 0, sizeof(item->gpuNewContext.thread));
  131. MemWrite(&item->gpuNewContext.period, 1E+09f / static_cast<float>(timestampFrequency));
  132. MemWrite(&item->gpuNewContext.context, m_context);
  133. MemWrite(&item->gpuNewContext.flags, GpuContextCalibration);
  134. MemWrite(&item->gpuNewContext.type, GpuContextType::Direct3D12);
  135. #ifdef TRACY_ON_DEMAND
  136. GetProfiler().DeferItem(*item);
  137. #endif
  138. Profiler::QueueSerialFinish();
  139. m_initialized = true;
  140. }
  141. void NewFrame()
  142. {
  143. m_payloadQueue.emplace(D3D12QueryPayload{ m_previousQueryCounter, m_queryCounter });
  144. m_previousQueryCounter += m_queryCounter;
  145. m_queryCounter = 0;
  146. if (m_previousQueryCounter >= m_queryLimit)
  147. {
  148. m_previousQueryCounter -= m_queryLimit;
  149. }
  150. m_queue->Signal(m_payloadFence.Get(), ++m_activePayload);
  151. }
  152. void Name( const char* name, uint16_t len )
  153. {
  154. auto ptr = (char*)tracy_malloc( len );
  155. memcpy( ptr, name, len );
  156. auto item = Profiler::QueueSerial();
  157. MemWrite( &item->hdr.type, QueueType::GpuContextName );
  158. MemWrite( &item->gpuContextNameFat.context, m_context );
  159. MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr );
  160. MemWrite( &item->gpuContextNameFat.size, len );
  161. #ifdef TRACY_ON_DEMAND
  162. GetProfiler().DeferItem( *item );
  163. #endif
  164. Profiler::QueueSerialFinish();
  165. }
  166. void Collect()
  167. {
  168. ZoneScopedC(Color::Red4);
  169. #ifdef TRACY_ON_DEMAND
  170. if (!GetProfiler().IsConnected())
  171. {
  172. m_queryCounter = 0;
  173. return;
  174. }
  175. #endif
  176. // Find out what payloads are available.
  177. const auto newestReadyPayload = m_payloadFence->GetCompletedValue();
  178. const auto payloadCount = m_payloadQueue.size() - (m_activePayload - newestReadyPayload);
  179. if (!payloadCount)
  180. {
  181. return; // No payloads are available yet, exit out.
  182. }
  183. D3D12_RANGE mapRange{ 0, m_queryLimit * sizeof(uint64_t) };
  184. // Map the readback buffer so we can fetch the query data from the GPU.
  185. void* readbackBufferMapping = nullptr;
  186. if (FAILED(m_readbackBuffer->Map(0, &mapRange, &readbackBufferMapping)))
  187. {
  188. assert(false && "Failed to map readback buffer.");
  189. }
  190. auto* timestampData = static_cast<uint64_t*>(readbackBufferMapping);
  191. for (uint32_t i = 0; i < payloadCount; ++i)
  192. {
  193. const auto& payload = m_payloadQueue.front();
  194. for (uint32_t j = 0; j < payload.m_queryCount; ++j)
  195. {
  196. const auto counter = (payload.m_queryIdStart + j) % m_queryLimit;
  197. const auto timestamp = timestampData[counter];
  198. const auto queryId = counter;
  199. auto* item = Profiler::QueueSerial();
  200. MemWrite(&item->hdr.type, QueueType::GpuTime);
  201. MemWrite(&item->gpuTime.gpuTime, timestamp);
  202. MemWrite(&item->gpuTime.queryId, static_cast<uint16_t>(queryId));
  203. MemWrite(&item->gpuTime.context, m_context);
  204. Profiler::QueueSerialFinish();
  205. }
  206. m_payloadQueue.pop();
  207. }
  208. m_readbackBuffer->Unmap(0, nullptr);
  209. // Recalibrate to account for drift.
  210. uint64_t cpuTimestamp;
  211. uint64_t gpuTimestamp;
  212. if (FAILED(m_queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp)))
  213. {
  214. assert(false && "Failed to get queue clock calibration.");
  215. }
  216. cpuTimestamp *= m_qpcToNs;
  217. const auto cpuDelta = cpuTimestamp - m_prevCalibration;
  218. if (cpuDelta > 0)
  219. {
  220. m_prevCalibration = cpuTimestamp;
  221. cpuTimestamp = Profiler::GetTime();
  222. auto* item = Profiler::QueueSerial();
  223. MemWrite(&item->hdr.type, QueueType::GpuCalibration);
  224. MemWrite(&item->gpuCalibration.gpuTime, gpuTimestamp);
  225. MemWrite(&item->gpuCalibration.cpuTime, cpuTimestamp);
  226. MemWrite(&item->gpuCalibration.cpuDelta, cpuDelta);
  227. MemWrite(&item->gpuCalibration.context, m_context);
  228. Profiler::QueueSerialFinish();
  229. }
  230. }
  231. private:
  232. tracy_force_inline uint32_t NextQueryId()
  233. {
  234. assert(m_queryCounter < m_queryLimit && "Submitted too many GPU queries! Consider increasing MaxQueries.");
  235. const uint32_t id = (m_previousQueryCounter + m_queryCounter) % m_queryLimit;
  236. m_queryCounter += 2; // Allocate space for a begin and end query.
  237. return id;
  238. }
  239. tracy_force_inline uint8_t GetId() const
  240. {
  241. return m_context;
  242. }
  243. };
  244. class D3D12ZoneScope
  245. {
  246. const bool m_active;
  247. D3D12QueueCtx* m_ctx = nullptr;
  248. ID3D12GraphicsCommandList* m_cmdList = nullptr;
  249. uint32_t m_queryId = 0; // Used for tracking in nested zones.
  250. public:
  251. tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, const SourceLocationData* srcLocation, bool active)
  252. #ifdef TRACY_ON_DEMAND
  253. : m_active(active && GetProfiler().IsConnected())
  254. #else
  255. : m_active(active)
  256. #endif
  257. {
  258. if (!m_active) return;
  259. m_ctx = ctx;
  260. m_cmdList = cmdList;
  261. m_queryId = ctx->NextQueryId();
  262. cmdList->EndQuery(ctx->m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, m_queryId);
  263. auto* item = Profiler::QueueSerial();
  264. MemWrite(&item->hdr.type, QueueType::GpuZoneBeginSerial);
  265. MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime());
  266. MemWrite(&item->gpuZoneBegin.srcloc, reinterpret_cast<uint64_t>(srcLocation));
  267. MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
  268. MemWrite(&item->gpuZoneBegin.queryId, static_cast<uint16_t>(m_queryId));
  269. MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
  270. Profiler::QueueSerialFinish();
  271. }
  272. tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, const SourceLocationData* srcLocation, int depth, bool active)
  273. #ifdef TRACY_ON_DEMAND
  274. : m_active(active&& GetProfiler().IsConnected())
  275. #else
  276. : m_active(active)
  277. #endif
  278. {
  279. if (!m_active) return;
  280. m_ctx = ctx;
  281. m_cmdList = cmdList;
  282. m_queryId = ctx->NextQueryId();
  283. cmdList->EndQuery(ctx->m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, m_queryId);
  284. auto* item = Profiler::QueueSerialCallstack(Callstack(depth));
  285. MemWrite(&item->hdr.type, QueueType::GpuZoneBeginCallstackSerial);
  286. MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime());
  287. MemWrite(&item->gpuZoneBegin.srcloc, reinterpret_cast<uint64_t>(srcLocation));
  288. MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
  289. MemWrite(&item->gpuZoneBegin.queryId, static_cast<uint16_t>(m_queryId));
  290. MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
  291. Profiler::QueueSerialFinish();
  292. }
  293. tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, ID3D12GraphicsCommandList* cmdList, bool active)
  294. #ifdef TRACY_ON_DEMAND
  295. : m_active(active&& GetProfiler().IsConnected())
  296. #else
  297. : m_active(active)
  298. #endif
  299. {
  300. if (!m_active) return;
  301. m_ctx = ctx;
  302. m_cmdList = cmdList;
  303. m_queryId = ctx->NextQueryId();
  304. cmdList->EndQuery(ctx->m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, m_queryId);
  305. const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz);
  306. auto* item = Profiler::QueueSerial();
  307. MemWrite(&item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocSerial);
  308. MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime());
  309. MemWrite(&item->gpuZoneBegin.srcloc, sourceLocation);
  310. MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
  311. MemWrite(&item->gpuZoneBegin.queryId, static_cast<uint16_t>(m_queryId));
  312. MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
  313. Profiler::QueueSerialFinish();
  314. }
  315. tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, ID3D12GraphicsCommandList* cmdList, int depth, bool active)
  316. #ifdef TRACY_ON_DEMAND
  317. : m_active(active&& GetProfiler().IsConnected())
  318. #else
  319. : m_active(active)
  320. #endif
  321. {
  322. if (!m_active) return;
  323. m_ctx = ctx;
  324. m_cmdList = cmdList;
  325. m_queryId = ctx->NextQueryId();
  326. cmdList->EndQuery(ctx->m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, m_queryId);
  327. const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz);
  328. auto* item = Profiler::QueueSerialCallstack(Callstack(depth));
  329. MemWrite(&item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial);
  330. MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime());
  331. MemWrite(&item->gpuZoneBegin.srcloc, sourceLocation);
  332. MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
  333. MemWrite(&item->gpuZoneBegin.queryId, static_cast<uint16_t>(m_queryId));
  334. MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
  335. Profiler::QueueSerialFinish();
  336. }
  337. tracy_force_inline ~D3D12ZoneScope()
  338. {
  339. if (!m_active) return;
  340. const auto queryId = m_queryId + 1; // Our end query slot is immediately after the begin slot.
  341. m_cmdList->EndQuery(m_ctx->m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, queryId);
  342. auto* item = Profiler::QueueSerial();
  343. MemWrite(&item->hdr.type, QueueType::GpuZoneEndSerial);
  344. MemWrite(&item->gpuZoneEnd.cpuTime, Profiler::GetTime());
  345. MemWrite(&item->gpuZoneEnd.thread, GetThreadHandle());
  346. MemWrite(&item->gpuZoneEnd.queryId, static_cast<uint16_t>(queryId));
  347. MemWrite(&item->gpuZoneEnd.context, m_ctx->GetId());
  348. Profiler::QueueSerialFinish();
  349. m_cmdList->ResolveQueryData(m_ctx->m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, m_queryId, 2, m_ctx->m_readbackBuffer.Get(), m_queryId * sizeof(uint64_t));
  350. }
  351. };
  352. static inline D3D12QueueCtx* CreateD3D12Context(ID3D12Device* device, ID3D12CommandQueue* queue)
  353. {
  354. InitRPMallocThread();
  355. auto* ctx = static_cast<D3D12QueueCtx*>(tracy_malloc(sizeof(D3D12QueueCtx)));
  356. new (ctx) D3D12QueueCtx{ device, queue };
  357. return ctx;
  358. }
  359. static inline void DestroyD3D12Context(D3D12QueueCtx* ctx)
  360. {
  361. ctx->~D3D12QueueCtx();
  362. tracy_free(ctx);
  363. }
  364. }
  365. using TracyD3D12Ctx = tracy::D3D12QueueCtx*;
  366. #define TracyD3D12Context(device, queue) tracy::CreateD3D12Context(device, queue);
  367. #define TracyD3D12Destroy(ctx) tracy::DestroyD3D12Context(ctx);
  368. #define TracyD3D12ContextName(ctx, name, size) ctx->Name(name, size);
  369. #define TracyD3D12NewFrame(ctx) ctx->NewFrame();
  370. #if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
  371. # define TracyD3D12Zone(ctx, cmdList, name) TracyD3D12NamedZoneS(ctx, ___tracy_gpu_zone, cmdList, name, TRACY_CALLSTACK, true)
  372. # define TracyD3D12ZoneC(ctx, cmdList, name, color) TracyD3D12NamedZoneCS(ctx, ___tracy_gpu_zone, cmdList, name, color, TRACY_CALLSTACK, true)
  373. # define TracyD3D12NamedZone(ctx, varname, cmdList, name, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location, __LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyConcat(__tracy_gpu_source_location, __LINE__), TRACY_CALLSTACK, active };
  374. # define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location, __LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyConcat(__tracy_gpu_source_location, __LINE__), TRACY_CALLSTACK, active };
  375. # define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active) TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, TRACY_CALLSTACK, active)
  376. #else
  377. # define TracyD3D12Zone(ctx, cmdList, name) TracyD3D12NamedZone(ctx, ___tracy_gpu_zone, cmdList, name, true)
  378. # define TracyD3D12ZoneC(ctx, cmdList, name, color) TracyD3D12NamedZoneC(ctx, ___tracy_gpu_zone, cmdList, name, color, true)
  379. # define TracyD3D12NamedZone(ctx, varname, cmdList, name, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location, __LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyConcat(__tracy_gpu_source_location, __LINE__), active };
  380. # define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location, __LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyConcat(__tracy_gpu_source_location, __LINE__), active };
  381. # define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active) tracy::D3D12ZoneScope varname{ ctx, __LINE__, __FILE__, strlen(__FILE__), __FUNCTION__, strlen(__FUNCTION__), name, strlen(name), cmdList, active };
  382. #endif
  383. #ifdef TRACY_HAS_CALLSTACK
  384. # define TracyD3D12ZoneS(ctx, cmdList, name, depth) TracyD3D12NamedZoneS(ctx, ___tracy_gpu_zone, cmdList, name, depth, true)
  385. # define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth) TracyD3D12NamedZoneCS(ctx, ___tracy_gpu_zone, cmdList, name, color, depth, true)
  386. # define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location, __LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyConcat(__tracy_gpu_source_location, __LINE__), depth, active };
  387. # define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location, __LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyConcat(__tracy_gpu_source_location, __LINE__), depth, active };
  388. # define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active) tracy::D3D12ZoneScope varname{ ctx, __LINE__, __FILE__, strlen(__FILE__), __FUNCTION__, strlen(__FUNCTION__), name, strlen(name), cmdList, depth, active };
  389. #else
  390. # define TracyD3D12ZoneS(ctx, cmdList, name, depth) TracyD3D12Zone(ctx, cmdList, name)
  391. # define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth) TracyD3D12Zone(ctx, cmdList, name, color)
  392. # define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active) TracyD3D12NamedZone(ctx, varname, cmdList, name, active)
  393. # define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active) TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active)
  394. # define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active) TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active)
  395. #endif
  396. #define TracyD3D12Collect(ctx) ctx->Collect();
  397. #endif
  398. #endif