feat: Tracy GPU 时间线——RG pass 级 GPU zone
RenderGraph 新增 IGpuProfiler 可选注入(pass 边界 Begin/End 钩子 + 帧尾 Collect,zone 覆盖 barrier+lambda+postBarriers),RG 本体不感知 任何 profiler 实现。Renderer 侧 TracyGpuProfiler 实现:TracyVkContext (校准用临时 cb,池必须带 RESET_COMMAND_BUFFER_BIT——tracy 校准流程 对同一 cb 连续 begin 三次)+ TracyVkZoneTransient(pass 名是运行时 字符串)。TRACY_ENABLE 关闭全链路退化为空。 用法:Tracy GUI(0.14.1 配对)连接后按 pass 名看 GPU 段时间线, 与 ImGui 数表互补;LOD 调优的测量前置。
This commit is contained in:
@@ -260,6 +260,24 @@ namespace Engine::RG {
|
||||
// pool 由调用方创建(容量 ≥ framesInFlight × queriesPerFrame),
|
||||
// 读取由调用方在本槽位 fence 等待之后进行。
|
||||
void SetQueryPool(vk::QueryPool pool, u32 queriesPerFrame);
|
||||
|
||||
// GPU profiler(可选):pass 边界的 GPU zone 钩子(Tracy 等工具的
|
||||
// 接缝,RG 本体不感知任何 profiler 实现)。BeginPass 返回的 scope
|
||||
// 析构 = 结束时间戳;注入者须保证 scope 生命周期覆盖 pass lambda。
|
||||
// EndFrame 在全部 pass 录制完后调用(仍在当帧 cmd 内,提交前)。
|
||||
class IGpuProfiler {
|
||||
public:
|
||||
virtual ~IGpuProfiler() = default;
|
||||
class IScope {
|
||||
public:
|
||||
virtual ~IScope() = default;
|
||||
};
|
||||
[[nodiscard]] virtual Scope<IScope> BeginPass(
|
||||
const char* name, vk::CommandBuffer cmd) = 0;
|
||||
virtual void EndFrame(vk::CommandBuffer cmd) = 0;
|
||||
};
|
||||
void SetGpuProfiler(IGpuProfiler* profiler) { m_GpuProfiler = profiler; }
|
||||
|
||||
std::vector<std::string> GetPassNames() const;
|
||||
|
||||
// ---- 统计 ----
|
||||
@@ -314,6 +332,7 @@ namespace Engine::RG {
|
||||
// GPU timestamp(可选注入)
|
||||
vk::QueryPool m_QueryPool{};
|
||||
u32 m_QueriesPerFrame = 0;
|
||||
IGpuProfiler* m_GpuProfiler = nullptr; // 非拥有(Renderer 持有)
|
||||
|
||||
// 物理资源池:key = (format, extent, usage),value = 空闲镜像列表
|
||||
struct PoolKey {
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace Engine {
|
||||
class Cubemap;
|
||||
class IblGenerator;
|
||||
class ImGuiLayer;
|
||||
class TracyGpuProfiler;
|
||||
|
||||
namespace ECS { class Scene; }
|
||||
namespace Assets { class AssetManager; class IAssetUploader; }
|
||||
@@ -172,6 +173,9 @@ namespace Engine {
|
||||
std::vector<f32> m_PassGpuMs; // 最近一帧各 pass 耗时
|
||||
bool m_TimesPrimed[2] = {false, false}; // 每槽位首帧跳过读取
|
||||
|
||||
// Tracy GPU 时间线(pass zone;TRACY_ENABLE 关闭时空实现)
|
||||
Scope<TracyGpuProfiler> m_TracyProfiler;
|
||||
|
||||
vk::Extent2D m_Extent{};
|
||||
u32 m_CurrentFrame = 0;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/24.
|
||||
//
|
||||
// TracyGpuProfiler:RG::IGpuProfiler 的 Tracy Vulkan 实现。
|
||||
//
|
||||
// 每个 RG pass 在 GPU 时间线里是一个 zone(TracyVkZoneTransient,运行时
|
||||
// 名字),时间戳在命令录制期写入当帧 cmd,TracyVkCollect 在帧尾解析。
|
||||
// TRACY_ENABLE 关闭时退化为空实现(零开销)。
|
||||
//
|
||||
// 时间戳未做 CPU/GPU 校准(TracyVkContext 非 calibrated 变体):
|
||||
// Tracy 按收集批次对齐,长时间运行的漂移可后续升级 Calibrated 变体。
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_TRACYGPUPROFILER_H
|
||||
#define HELLOVULKAN_TRACYGPUPROFILER_H
|
||||
|
||||
#include <Engine/RenderGraph/RenderGraph.h>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Device;
|
||||
|
||||
class TracyGpuProfiler final : public RG::RenderGraph::IGpuProfiler {
|
||||
public:
|
||||
explicit TracyGpuProfiler(Device& device);
|
||||
~TracyGpuProfiler() override;
|
||||
|
||||
TracyGpuProfiler(const TracyGpuProfiler&) = delete;
|
||||
TracyGpuProfiler& operator=(const TracyGpuProfiler&) = delete;
|
||||
|
||||
[[nodiscard]] Scope<IScope> BeginPass(const char* name,
|
||||
vk::CommandBuffer cmd) override;
|
||||
void EndFrame(vk::CommandBuffer cmd) override;
|
||||
private:
|
||||
class ScopeImpl;
|
||||
void* m_Ctx{}; // tracy::VkCtx*(TracyVulkan.hpp 只在实现内 include)
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_TRACYGPUPROFILER_H
|
||||
Reference in New Issue
Block a user