修复clash的问题
This commit is contained in:
+23
-35
@@ -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, ©Region);
|
||||
|
||||
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, ©Region);
|
||||
});
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user