mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-17 17:43:52 +00:00
fix(rendering): defer character renderer bone descriptor destruction
CharacterRenderer::destroyInstanceBones had the same immediate-free bug as M2Renderer — freeing bone descriptor sets and buffers while in-flight command buffers still reference them. Applies the same deferred pattern via deferAfterFrameFence for the removeInstance streaming path.
This commit is contained in:
parent
345b41b810
commit
e19bf76d88
2 changed files with 31 additions and 13 deletions
|
|
@ -209,7 +209,7 @@ private:
|
||||||
glm::mat4 getBoneTransform(const pipeline::M2Bone& bone, float time, int sequenceIndex);
|
glm::mat4 getBoneTransform(const pipeline::M2Bone& bone, float time, int sequenceIndex);
|
||||||
glm::mat4 getModelMatrix(const CharacterInstance& instance) const;
|
glm::mat4 getModelMatrix(const CharacterInstance& instance) const;
|
||||||
void destroyModelGPU(M2ModelGPU& gpuModel);
|
void destroyModelGPU(M2ModelGPU& gpuModel);
|
||||||
void destroyInstanceBones(CharacterInstance& inst);
|
void destroyInstanceBones(CharacterInstance& inst, bool defer = false);
|
||||||
|
|
||||||
// Keyframe interpolation helpers
|
// Keyframe interpolation helpers
|
||||||
static int findKeyframeIndex(const std::vector<uint32_t>& timestamps, float time);
|
static int findKeyframeIndex(const std::vector<uint32_t>& timestamps, float time);
|
||||||
|
|
|
||||||
|
|
@ -479,20 +479,37 @@ void CharacterRenderer::destroyModelGPU(M2ModelGPU& gpuModel) {
|
||||||
if (gpuModel.indexBuffer) { vmaDestroyBuffer(alloc, gpuModel.indexBuffer, gpuModel.indexAlloc); gpuModel.indexBuffer = VK_NULL_HANDLE; }
|
if (gpuModel.indexBuffer) { vmaDestroyBuffer(alloc, gpuModel.indexBuffer, gpuModel.indexAlloc); gpuModel.indexBuffer = VK_NULL_HANDLE; }
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterRenderer::destroyInstanceBones(CharacterInstance& inst) {
|
void CharacterRenderer::destroyInstanceBones(CharacterInstance& inst, bool defer) {
|
||||||
if (!vkCtx_) return;
|
if (!vkCtx_) return;
|
||||||
VmaAllocator alloc = vkCtx_->getAllocator();
|
VmaAllocator alloc = vkCtx_->getAllocator();
|
||||||
VkDevice device = vkCtx_->getDevice();
|
VkDevice device = vkCtx_->getDevice();
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (inst.boneSet[i] != VK_NULL_HANDLE && boneDescPool_ != VK_NULL_HANDLE) {
|
VkDescriptorSet boneSet = inst.boneSet[i];
|
||||||
vkFreeDescriptorSets(device, boneDescPool_, 1, &inst.boneSet[i]);
|
::VkBuffer boneBuf = inst.boneBuffer[i];
|
||||||
inst.boneSet[i] = VK_NULL_HANDLE;
|
VmaAllocation boneAlloc = inst.boneAlloc[i];
|
||||||
}
|
inst.boneSet[i] = VK_NULL_HANDLE;
|
||||||
if (inst.boneBuffer[i]) {
|
inst.boneBuffer[i] = VK_NULL_HANDLE;
|
||||||
vmaDestroyBuffer(alloc, inst.boneBuffer[i], inst.boneAlloc[i]);
|
inst.boneAlloc[i] = VK_NULL_HANDLE;
|
||||||
inst.boneBuffer[i] = VK_NULL_HANDLE;
|
inst.boneMapped[i] = nullptr;
|
||||||
inst.boneAlloc[i] = VK_NULL_HANDLE;
|
|
||||||
inst.boneMapped[i] = nullptr;
|
if (!defer) {
|
||||||
|
if (boneSet != VK_NULL_HANDLE && boneDescPool_ != VK_NULL_HANDLE) {
|
||||||
|
vkFreeDescriptorSets(device, boneDescPool_, 1, &boneSet);
|
||||||
|
}
|
||||||
|
if (boneBuf) {
|
||||||
|
vmaDestroyBuffer(alloc, boneBuf, boneAlloc);
|
||||||
|
}
|
||||||
|
} else if (boneSet != VK_NULL_HANDLE || boneBuf) {
|
||||||
|
VkDescriptorPool pool = boneDescPool_;
|
||||||
|
vkCtx_->deferAfterFrameFence([device, alloc, pool, boneSet, boneBuf, boneAlloc]() {
|
||||||
|
if (boneSet != VK_NULL_HANDLE && pool != VK_NULL_HANDLE) {
|
||||||
|
VkDescriptorSet s = boneSet;
|
||||||
|
vkFreeDescriptorSets(device, pool, 1, &s);
|
||||||
|
}
|
||||||
|
if (boneBuf) {
|
||||||
|
vmaDestroyBuffer(alloc, boneBuf, boneAlloc);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2953,8 +2970,9 @@ void CharacterRenderer::removeInstance(uint32_t instanceId) {
|
||||||
removeInstance(wa.weaponInstanceId);
|
removeInstance(wa.weaponInstanceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy bone buffers for this instance
|
// Defer bone buffer destruction — in-flight command buffers may still
|
||||||
destroyInstanceBones(it->second);
|
// reference these descriptor sets.
|
||||||
|
destroyInstanceBones(it->second, /*defer=*/true);
|
||||||
|
|
||||||
instances.erase(it);
|
instances.erase(it);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue