8

In the API-Samples that come with Vulkan, it appears that there is always a call to vkWaitForFences after a call to vkQueueSubmit, either directly or via execute_queue_command_buffer (in util_init.hpp). The call to vkWaitForFences will block the CPU execution until the GPU has finished doing all the work in the previous vkQueueSubmit. This in effect doesn't allow multiple frames to be constructed simultaneously, which (in theory) is limiting performance significantly.

Are these calls required, and if so, is there another way to not require the GPU to be idle before constructing a new frame?

MuertoExcobito
  • 9,741
  • 2
  • 37
  • 78

1 Answers1

8

The way we achieved multiple frames in flight is to have a fence for each swapchain framebuffer you have. Then still use the vkWaitForFences but wait for the ((n+1)%num_fences) fence.

There is example code here https://imgtec.com/tools/powervr-early-access-program/

uint32_t current_buffer = num_swaps_ % swapchain_fences.size();
vkQueueSubmit(graphics_queue, 1, &submit_info, swapchain_fences[current_buffer]);
// Wait for a queuesubmit to finish so we can continue rendering if we are n-2 frames behind
if(num_swaps_ > swapchain_fences.size() - 1)
{
    uint32_t fence_to_wait_for = (num_swaps_ + 1) % swapchain_fences.size();
    vkWaitForFences(device, 1, &swapchain_fences[fence_to_wait_for], true, UINT64_MAX);
    vkResetFences(device, 1, &swapchain_fences[current_buffer]);
}
ashleysmithgpu
  • 1,867
  • 20
  • 39
  • 1
    But coding this is a bit trickier because you can't change any buffers that are still being used by the frames in flight. – ratchet freak Feb 23 '16 at 10:05
  • Yes it is quite a bit more complicated :) You will need to multi-buffer UBOs so that you don't write over data that the GPU is using. You also need to worry about pipeline barriers so a cache doesn’t give you old data. There are examples of both in that link. – ashleysmithgpu Feb 23 '16 at 10:44