修复碎片模型卸载的在飞 GPU 引用(vkDestroyBuffer in-use):门面批量卸载先 WaitDeviceIdle 再销毁(与 ReloadMaterialAsset 同一先例)

This commit is contained in:
2026-10-08 23:23:15 +08:00
parent affa1a7a56
commit 2cf8d6e076
2 changed files with 24 additions and 18 deletions
+14 -14
View File
@@ -259,19 +259,20 @@ namespace {
}
// 墙销毁(PIE stop 换血 / 手动删除):碎片实体由场景清亡处理,
// 独占碎片模型全部回收(模型不被快照恢复的场景引用——唯一代键)
// 独占碎片模型统一批量回收(模型不被快照恢复的场景引用——
// 唯一代键;批量接口内部 GPU 停飞后再销毁)
void OnDestroy() override {
auto& assets = App().GetAssets();
std::vector<std::string> paths;
paths.reserve(m_Fragments.size() + m_PendingUnload.size());
for (const Fragment& f : m_Fragments) {
if (!f.modelPath.empty()) {
assets.UnloadModelByPath(f.modelPath);
}
if (!f.modelPath.empty()) paths.push_back(f.modelPath);
}
m_Fragments.clear();
for (const std::string& p : m_PendingUnload) {
assets.UnloadModelByPath(p);
}
paths.insert(paths.end(),
std::make_move_iterator(m_PendingUnload.begin()),
std::make_move_iterator(m_PendingUnload.end()));
m_PendingUnload.clear();
App().GetAssets().UnloadModelsByPaths(paths);
}
private:
@@ -449,13 +450,12 @@ namespace {
}
}
// ---- 模型回收:延迟一帧执行(Destroy 是帧尾延迟,碎片实体
// 本帧渲染收集仍会引用模型;下一帧实体已灭,卸载才安全)----
// ---- 模型回收:延迟一帧 + 批量停飞卸载(Destroy 是帧尾延迟,
// 碎片实体本帧渲染收集仍会引用模型;下一帧实体已灭,但上一帧
// 提交的命令缓冲仍可能引用顶点缓冲/sampler——批量接口先
// WaitDeviceIdle 再销毁,与资产重建换绑同一引擎先例)----
void ApplyPendingUnload() {
auto& assets = App().GetAssets();
for (const std::string& p : m_PendingUnload) {
assets.UnloadModelByPath(p);
}
App().GetAssets().UnloadModelsByPaths(m_PendingUnload);
m_PendingUnload.clear();
}