feat: RenderGraph GPU timestamp profiling

- RG::SetQueryPool 可选注入;Execute 期每 pass 前后各写一枚
  writeTimestamp2(BOTTOM_OF_PIPE),索引按帧槽位分区 + 执行序排布
- 每帧录制开头 reset 本槽位查询区间(上一轮结果已在 fence 等待后读取)
- Renderer 在 WaitFence 后读 64bit 结果换算毫秒(timestampPeriod 缓存),
  经 GetPassNames/GetPassGpuMs 透出给 ImGui 面板显示
- 每槽位首帧跳过读取(查询尚未 primed,避免 VUID-09401)
This commit is contained in:
2026-09-22 19:25:42 +08:00
parent 908e688178
commit 41e4cc85d5
5 changed files with 120 additions and 0 deletions
@@ -227,6 +227,13 @@ namespace Engine::RG {
// 每帧执行:按编译好的顺序录命令。要求 cmd 处于 recording 状态。
void Execute(const FrameContext& frame);
// GPU timestamp(可选):注入 pool 后,每个 pass 前后各写一枚
// 时间戳,索引 = frameSlot * queriesPerFrame + 执行序位置 * 2。
// pool 由调用方创建(容量 ≥ framesInFlight × queriesPerFrame),
// 读取由调用方在本槽位 fence 等待之后进行。
void SetQueryPool(vk::QueryPool pool, u32 queriesPerFrame);
std::vector<std::string> GetPassNames() const;
// ---- 统计 ----
u32 GetPassCount() const;
@@ -276,6 +283,10 @@ namespace Engine::RG {
// 拓扑排序后的执行序(存 pass 下标)
std::vector<u32> m_ExecutionOrder;
// GPU timestamp(可选注入)
vk::QueryPool m_QueryPool{};
u32 m_QueriesPerFrame = 0;
// 物理资源池:key = (format, extent, usage),value = 空闲镜像列表
struct PoolKey {
u32 format;
+13
View File
@@ -65,6 +65,7 @@ namespace Engine {
void HandleResize();
void UpdateShadowDescriptors();
void UpdateFullscreenDescriptors();
void ReadGpuTimes(u32 frameSlot);
Window& m_Window;
@@ -136,6 +137,14 @@ namespace Engine {
f32 m_BloomThreshold = 1.0f; // HDR 域亮度阈值
f32 m_BloomStrength = 0.8f; // 叠加强度
// GPU timestamp(pass 级耗时,ImGui 可读)
vk::QueryPool m_QueryPool;
u32 m_QueriesPerFrame = 0; // 每帧槽位的查询数 = pass 数 × 2
f32 m_TimestampPeriod = 1.0f; // ns/tick(设备属性缓存)
std::vector<std::string> m_PassNames; // 执行序 pass 名
std::vector<f32> m_PassGpuMs; // 最近一帧各 pass 耗时
bool m_TimesPrimed[2] = {false, false}; // 每槽位首帧跳过读取
public:
f32 GetExposure() const { return m_Exposure; }
void SetExposure(f32 e) { m_Exposure = e; }
@@ -146,6 +155,10 @@ namespace Engine {
f32 GetBloomStrength() const { return m_BloomStrength; }
void SetBloomStrength(f32 v) { m_BloomStrength = v; }
// pass 级 GPU 耗时(最近完成帧,毫秒;与 GetPassGpuMs 下标对应)
const std::vector<std::string>& GetPassNames() const { return m_PassNames; }
const std::vector<f32>& GetPassGpuMs() const { return m_PassGpuMs; }
private:
vk::Extent2D m_Extent{};