void drawFrame() {
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, std::numeric_limits<uint64_t>::max());
...
VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]};
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores;
vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame])
...
VkSwapchainKHR swapChains[] = {swapChain};
VkPresentInfoKHR presentInfo = {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = signalSemaphores;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = swapChains;
presentInfo.pImageIndices = &imageIndex;
vkQueuePresentKHR(presentQueue, &presentInfo); // <- vkQueuePresentKHR
...
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
}
VkQueuePresentKHR在提交第一帧vkQueueSubmit之后被要求发出先发信息,在第二帧中,调用vkWaitForFences等待前一帧的vkQueueSubmit结束,然后再次调用vkQueueSubmit进行提交,但是此时vkQueuePresentKHR的第一帧可能在渲染中,它占据了第一帧的帧缓冲区。那么第二帧的vkQueueSubmit是否会与第一帧的vkQueuePresentKHR冲突?
我认为可能有两种情况:
1:第一帧和第二帧不占用相同的帧缓冲区,当第一帧vkQueueSubmit结束时,数据已被复制到新的内存中。 vkQueuePresentKHR将数据显示在新的内存中,因此将第二帧渲染到帧缓冲区不会影响第一帧的内容。
2:第一帧和第二帧占用相同的帧缓冲区,当第一帧的vkQueuePresentKHR和第二帧的vkQueueSubmit同时使用帧缓冲区时,会发生图像撕裂(我想)。 >
我认为第二种可能性会更高。
我想将结果呈现到我自己的内存中,而不是将其呈现在屏幕上。我想弄清楚vkQueuePresentKHR的作用。
这里是渲染到您自己的内存的示例:https://github.com/SaschaWillems/Vulkan/blob/master/examples/renderheadless/renderheadless.cpp
在此示例中,渲染的帧缓冲区数据被传输到新的内存。
在我设计的程序中,有一个辅助线程负责等待栅栏完成。传输完成后将使用此内存。类似于下面的示例:
主线程:
void drawFrame() { vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, std::numeric_limits<uint64_t>::max()); ... VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]}; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; // VkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]) cannot be executed before the execution of // vkQueueSubmit(graphicsQueue, 1, &transferSubmitInfo, transferCompleteFences[currentFrame]) in the previous frame. Otherwise, // they will occupy the same FrameBuffer. I think it is not possible. transferCompleteMutexs[currentFrame].lock(); // <- lock transferCompleteMutexs vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]) ... VkSubmitInfo transferSubmitInfo = {}; transferSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; transferSubmitInfo.commandBufferCount = 1; transferSubmitInfo.pCommandBuffers = &commandBuffer; transferSubmitInfo.waitSemaphoreCount = 1; transferSubmitInfo.pWaitSemaphores = signalSemaphores; vkQueueSubmit(graphicsQueue, 1, &transferSubmitInfo, transferCompleteFences[currentFrame]) // Signal <- transferCompleteFences ... }
第二线程:
保护FrameBuffer,我认为这是必要的。但是显然vkQueuePresentKHR不会这样做。我是否有更好的方法来模拟vkQueuePresentKHR以将数据呈现到我自己的内存中,或者我现在正在做是否正确?while(true) { // Waiting for transfer to complete vkWaitForFences(logicalDevice_->vkLogicalDevice(), 1, &transferCompleteFences[currentFrame], // Wait <- transferCompleteFences VK_TRUE, std::numeric_limits<uint64_t>::max()); // using transfer completed data ... // Secondary thread knows that the current frame is transmitted. The next Primary thread can be submitted. transferCompleteMutexs[currentFrame].unlock(); // <- unlock transferCompleteMutexs }
上面的代码使用transferCompleteMutexs
void drawFrame(){vkWaitForFences(device,1,&inFlightFences [currentFrame],VK_TRUE,std :: numeric_limits
第二帧的vkQueueSubmit
不能与第一帧的vkQueuePresent
“冲突”。