Surface capabilities always return min/max number of images that are out of bounds [Discussion]
I'd like to start a discussion about a bug I've found on anv before I send a patch because I am not sure about the use of tripple buffering inside the Vulkan driver.
The problem:
When creating a swapchain we usually query the surface capabilities using vkGetPhysicalDeviceSurfaceCapabilitiesKHR
. The minimum and maximum images numbers returned by anv are always out of bounds: minImageCount
is 3 and maxImageCount
is 0! This obviously causes a validation error and maybe further problems.
Checking the anv code I've seen that the maxImageCount
is always hard coded to 0 and there's a comment that there's no real maximum. I think this is not correct because 0 will always cause an out of bounds error.
But there's another problem as well: the minimum is taken by the function x11_get_min_image_count
which returns 3 and has this comment:
/* For IMMEDIATE and FIFO, most games work in a pipelined manner where the
* can produce frames at a rate of 1/MAX(CPU duration, GPU duration), but
* the render latency is CPU duration + GPU duration.
*
* This means that with scanout from pageflipping we need 3 frames to run
* full speed:
* 1) CPU rendering work
* 2) GPU rendering work
* 3) scanout
*
* Once we have a nonblocking acquire that returns a semaphore we can merge
* 1 and 3. Hence the ideal implementation needs only 2 images, but games
* cannot tellwe currently do not have an ideal implementation and that
* hence they need to allocate 3 images. So let us do it for them.
*
* This is a tradeoff as it uses more memory than needed for non-fullscreen
* and non-performance intensive applications.
*/
return 3;
I believe that:
1- we shouldn't force triple buffering and use a minImageCount < 3
(to avoid the latency problems)
2- we shouldn't set the maximum image count to 0 (because this way we will always get the validation error and out of bounds numbers)
My questions are:
- Does Vulkan support single buffering? If so, I think we should set the minimum to 1, else to 2. (Nvidia returns 2 so, maybe double buffering is always required?)
- What about using a maximum image count that makes sense and is >= 3? Nvidia returns 8 but I don't know how this number is selected. Is there a reason we want to always force triple buffering or is it a bug? I think it would make more sense to leave this decision to the user because the latency with 3 images is high.