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.
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.