修复clash的问题

This commit is contained in:
xsl
2026-04-25 16:42:20 +08:00
parent 2066b3b124
commit 50680ee854
8 changed files with 893 additions and 64 deletions
+23 -35
View File
@@ -889,6 +889,12 @@ void FaceApp::onWindowLost()
std::unique_lock<std::mutex> lk_point(mtx_point);
std::unique_lock<std::mutex> lk_motion(changeMotionMtx);
std::unique_lock<std::mutex> lk_tex(createTextureMtx);
// 同时阻塞所有并发的 GPU 提交(drawFrame / copyBuffer / updateTexture)。
// cleanupForWindowLost() 会执行 vkDeviceWaitIdle 并销毁 swapchain / surface /
// semaphores / fences 等窗口相关资源,如果此时有其它线程正在 vkQueueSubmit
// 或 vkQueuePresentKHR,会触发 FORTIFY: pthread_mutex_lock called on a
// destroyed mutex。这里持锁确保销毁与提交是互斥的。
std::unique_lock<std::mutex> lk_pool(poolQueueMtx);
Application::cleanupForWindowLost();
_secondfaceAppInited = false;
@@ -1053,41 +1059,20 @@ void FaceApp::update_face_vertex_buffer(float* pos, int pointCount)
void FaceApp::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size)
{
VkCommandBuffer commandBuffer = beginSingleTimeCommands();
VkBufferCopy copyRegion = {};
copyRegion.size = size;
vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &copyRegion);
endSingleTimeCommands(commandBuffer);
}
VkCommandBuffer FaceApp::beginSingleTimeCommands() {
VkCommandBufferAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandPool = commandPool;
allocInfo.commandBufferCount = 1;
VkCommandBuffer commandBuffer;
vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer);
VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
vkBeginCommandBuffer(commandBuffer, &beginInfo);
return commandBuffer;
}
void FaceApp::endSingleTimeCommands(VkCommandBuffer commandBuffer) {
vkEndCommandBuffer(commandBuffer);
VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer;
vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
vkQueueWaitIdle(graphicsQueue);
vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
// 改造说明:
// 旧实现是 vkAllocate(commandPool) + vkBegin + vkCmdCopyBuffer + vkEnd +
// vkQueueSubmit(graphicsQueue) + vkQueueWaitIdle + vkFree(commandPool)
// 每帧 update_face_vertex_buffer 会调两次 copyBuffer(顶点 + 索引),
// 长期高频 allocate/free 会把驱动 per-pool mutex 玩坏,触发
// FORTIFY: pthread_mutex_lock called on a destroyed mutex。
//
// 现在改走基类的 runTransferCommand,复用 commandPool_ex 上预分配的
// 3 个 cmdbuf + fence,并发安全由 m_xferMtx + poolQueueMtx 联合保证。
runTransferCommand([&](VkCommandBuffer commandBuffer) {
VkBufferCopy copyRegion = {};
copyRegion.size = size;
vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &copyRegion);
});
}
void FaceApp::createUniformBuffer()
@@ -1458,6 +1443,9 @@ void FaceApp::cleanup()
//}
destroyTexture(device, tex_bg);
// 必须在销毁 commandPool_ex 之前释放从它分配的 transfer cmdbuf + fence。
// vkDeviceWaitIdle 已在本函数开头调过,提交不会再有 in-flight。
destroyTransferResources();
vkDestroyCommandPool(device, commandPool, nullptr);
vkDestroyCommandPool(device, commandPool_ex, nullptr);
Application::cleanup();