// // Created by atdunbg on 2026/9/24. // #include #include #include #include #include namespace Engine { // pass scope:构造 = BEGIN 时间戳,析构 = END(覆盖 pass lambda 录制期) class TracyGpuProfiler::ScopeImpl final : public RG::RenderGraph::IGpuProfiler::IScope { public: #ifdef TRACY_ENABLE ScopeImpl(TracyVkCtx ctx, const char* name, vk::CommandBuffer cmd) : m_Zone(ctx, static_cast(__LINE__), __FILE__, sizeof(__FILE__) - 1, __FUNCTION__, sizeof(__FUNCTION__) - 1, name, std::strlen(name), static_cast(cmd), true) {} tracy::VkCtxScope m_Zone; #else ScopeImpl(TracyVkCtx, const char*, vk::CommandBuffer) {} #endif }; TracyGpuProfiler::TracyGpuProfiler(Device& device) { #ifdef TRACY_ENABLE // 校准用临时 command buffer:tracy 校准流程对同一 cb 连续 // begin 三次(无中间 reset)——池必须带 RESET_COMMAND_BUFFER_BIT, // 否则 VUID-vkBeginCommandBuffer-commandBuffer-00050 vk::CommandPoolCreateInfo poolInfo; poolInfo.setQueueFamilyIndex(device.GetGraphicsFamily()) .setFlags(vk::CommandPoolCreateFlagBits::eTransient | vk::CommandPoolCreateFlagBits::eResetCommandBuffer); vk::CommandPool pool = device.GetDevice().createCommandPool(poolInfo); vk::CommandBuffer cb = device.GetDevice().allocateCommandBuffers( vk::CommandBufferAllocateInfo{} .setCommandPool(pool) .setLevel(vk::CommandBufferLevel::ePrimary) .setCommandBufferCount(1))[0]; m_Ctx = TracyVkContext( static_cast(device.GetPhysicalDevice()), static_cast(device.GetDevice()), static_cast(device.GetGraphicsQueue()), static_cast(cb)); device.GetDevice().freeCommandBuffers(pool, cb); device.GetDevice().destroyCommandPool(pool); if (m_Ctx) { ENGINE_INFO("Tracy GPU profiler attached (pass zones active)"); } else { ENGINE_WARN("Tracy GPU profiler: context creation failed, disabled"); } #endif } TracyGpuProfiler::~TracyGpuProfiler() { #ifdef TRACY_ENABLE if (m_Ctx) { TracyVkDestroy(static_cast(m_Ctx)); } #endif } Scope TracyGpuProfiler::BeginPass( const char* name, vk::CommandBuffer cmd) { #ifdef TRACY_ENABLE if (!m_Ctx) return nullptr; return Scope(new ScopeImpl( static_cast(m_Ctx), name, cmd)); #else (void)name; (void)cmd; return nullptr; #endif } void TracyGpuProfiler::EndFrame(vk::CommandBuffer cmd) { #ifdef TRACY_ENABLE if (m_Ctx) { TracyVkCollect(static_cast(m_Ctx), static_cast(cmd)); } #else (void)cmd; #endif } } // namespace Engine