Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does vkAcquireNextImageKHR() never block my thread?

I am using Vulkan graphics API (via BGFX) to render. And I have been measuring how much (wall-clock) time my calls take.

What I do not understand is that vkAcquireNextImageKHR() is always fast, and never blocks. Even though I disable the time-out and use a semaphore to wait for presentation.

The presentation is locked to a 60Hz display rate, and I see my main-loop indeed run at 16.6 or 33.3 ms.

Shouldn't I see the wait-time for this display rate show up in the length of the vkAcquireNextImageKHR() call?

The profiler measures this call as 0.2ms or so, and never a substantial part of a frame.

VkResult result = vkAcquireNextImageKHR(
    m_device
  , m_swapchain
  , UINT64_MAX
  , renderWait
  , VK_NULL_HANDLE
  , &m_backBufferColorIdx
);

Target hardware is a handheld console.

like image 554
Bram Avatar asked Feb 26 '20 17:02

Bram


1 Answers

The whole purpose of Vulkan is to alleviate CPU bottlenecks. Making the CPU stop until the GPU is ready for something would be the opposite of that. Especially if the CPU itself isn't actually going to use the result of this operation.

As such, all vkAcquireNextImageKHR function does is let you know which image will be made available to you next. This is the minimum that needs to happen in order for you to be able to use that image (for example, by building command buffers that reference the image in some way). However, that image is not yet available to you.

This is why this function requires you to provide a semaphore and/or a fence: so that the process which consumes the image can wait for the image to be made available.

If the process which consumes the image is just a bunch of commands in a command buffer (ie: something you submit with vkQueueSubmit), you can simply have that batch of work wait on the semaphore given to the acquire operation. That means all of the waiting happens in the GPU. Where it belongs.

The fence is there if you (for some reason) want the CPU to be able to wait until the acquire is done. But Vulkan, as an explicit, low-level API, forces you to explicitly say that this is what you want (and it almost never is what you want).

like image 105
Nicol Bolas Avatar answered Oct 01 '22 23:10

Nicol Bolas