Search code examples
c++graphics3dvulkan

Does vkQueuePresentKHR prevent later commands from executing while it is waiting on the semaphore?


This is kind of a follow-up question for this question, and it is also based on the code provided by the same Vulkan tutorial.

Here is a simplified example:

// Vulkan handles defined and initialized elsewhere
VkDevice device;
VkQueue queue;
VkSempahore semaphore;
VkSwapchain swapchain;
VkCommandBuffer cmd_buffer;

// Renderer code
uint32_t image_index;   // image acquisition is omitted

VkPresentInfoKHR present_info{};
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = &semaphore;
present_info.swapchainCount = 1;
present_info.pSwapchains = &swapchain;
present_info.pImageIndices = &image_index;

VkSubmitInfo submit_info{};
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
// ... irrelevant code omitted
submit_info.pCommandBuffers = &cmd_buffer;

vkQueuePresentKHR(queue, &present_info);
vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);

In the above example, will the commands in cmd_buffer also have to wait until semaphore is signaled?


I am asking about this because a comment below the tutorial mentioned that:

However, if the graphics and present queue do end up being the same, then the renderFinished semaphore guarantees proper execution ordering. This is because the vkQueuePresentKHR command waits on that semaphore and it must begin before later commands in the queue begin (due to implicit ordering) and that only happens after rendering from the previous frame finished.


Solution

  • In the above example, will the commands in cmd_buffer also have to wait until semaphore is signaled?

    Only if you use the semaphore as a waitSemaphore for the later submit.

    This is because the vkQueuePresentKHR command waits on that semaphore and it must begin before later commands in the queue begin (due to implicit ordering) and that only happens after rendering from the previous frame finished.

    I don't believe this is true.

    Commands start in implicit order with respect to other commands in the queue, but this is pipelined on a stage-to-stage basis. Also note the spec wording says "start in order" not "complete in order", which is a specification sleight of hand. Hardware is perfectly free to overlap and out-of-order execution of individual commands that are otherwise sequential in the stream unless the stream contains synchronization primitives that stop it doing so.