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 вызывается для presont после отправки первого кадра vkQueueSubmit. Во втором кадре вызовите vkWaitForFences, чтобы дождаться окончания vkQueueSubmit предыдущего кадра, а затем снова вызовите vkQueueSubmit для фиксации, но на этом этапеПервый кадр vkQueuePresentKHR может быть в рендеринге, он занимает кадровый буфер первого кадра. Так будет ли vkQueueSubmit второго кадра конфликтовать с vkQueuePresentKHR первого кадра?
Я думаю, что может быть две ситуации:
1 : Первый кадр ивторой кадр не занимает один и тот же кадровый буфер , Когда первый кадр vkQueueSubmit заканчивается, данные были скопированы в новую память. vkQueuePresentKHR представляет данные в новой памяти, поэтому рендеринг второго кадра в буфер кадров не влияет на содержимое первого кадра.
2: первый кадр и второй кадр занимают один и тот же кадровый буфер , Когда vkQueuePresentKHRпервого кадра и vkQueueSubmit второго кадра одновременно используют Framebuffer, происходит разрыв изображения (я думаю).
Я думаю, что вторая возможность будет выше.
Я хочу отобразить результат в моей собственной памяти, а не предварительно отобразить его на экране. Я хочу выяснить, что делает vkQueuePresentKHR.
Вот пример рендеринга в вашу собственную память: https://github.com/SaschaWillems/Vulkan/blob/master/examples/renderheadless/renderheadless.cpp
В этом примере визуализированные данные Framebuffer переносятся в новую память.
В разработанной мною программе есть дополнительный поток, отвечающий за ожидание завершения Fence. Эта память используется после завершения передачи. Аналогично приведенному ниже примеру:
Основной поток:
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
...
}
Вторичный поток:
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 для защиты FrameBufferЯ думаю, что это необходимо. Но очевидно, что vkQueuePresentKHR этого не делает. У меня есть лучший способ эмулировать vkQueuePresentKHR для отображения данных в моей собственной памяти, или это правильно, что я делаю сейчас?