fix: Shadow pass 接入 GPUDriven batch,实例上限提至 16384

100 背包掉帧 + 警告刷屏的根因与修复:
1. backpack.obj 有 44 个 mesh 部件,100 实体 × 44 = 4400 实例
   打爆 4096 上限 → 每帧截断 + 告警刷屏。上限提至 16384
  (1MB/slot),告警改一次性
2. Shadow pass 仍逐实体逐部件画(4400 draw,CPU 提交瓶颈)。
   改为与 Forward 共用同一批 batch:Set0 绑 ObjectBuffer,
   lightVP 一次 push,44 draw 完成。shadow.vert 经
   gl_InstanceIndex 从 SSBO 取模型矩阵
3. 遥测补全:Application::Run 每 120 帧输出 CPU 归属
   (update/ui/render/total),Render 输出实例收集耗时——
   实测 100 背包 CPU 2.0ms/帧 GPU 0.6ms/帧 ≈ 500fps
This commit is contained in:
2026-09-22 20:17:05 +08:00
parent 6a3fcac072
commit cef32ea1ba
3 changed files with 26 additions and 0 deletions
+4
View File
@@ -851,6 +851,7 @@ namespace Engine
line += " " + m_PassNames[i] + "=" +
std::to_string(m_PassGpuMs[i]).substr(0, 5) + "ms";
}
line += " collect=" + std::to_string(m_CollectMs).substr(0, 5) + "ms";
ENGINE_INFO("{}", line);
}
}
@@ -939,6 +940,7 @@ namespace Engine
// 两趟遍历:先收集唯一 mesh(保持首现序),再逐 batch 追加实例矩阵,
// 保证每个 batch 的矩阵区间连续(draw 用 firstInstance 指向起点)。
// TODO: 实体量大时改哈希聚合 + 单趟填充
const auto collectStart = std::chrono::steady_clock::now();
m_InstanceBatches.clear();
m_InstanceModels.clear();
bool instanceTruncated = false;
@@ -990,6 +992,8 @@ namespace Engine
m_ObjectBuffer->Update(frameSlot, m_InstanceModels.data(),
m_InstanceModels.size() * sizeof(glm::mat4));
}
m_CollectMs = std::chrono::duration<f32, std::milli>(
std::chrono::steady_clock::now() - collectStart).count();
// 2. acquire swapchain image
u32 imageIndex = 0;