About the swapchain image resizing

Some time ago I implemented swapchain image resizing in my Vulkan renderer
using system events ( WM_SIZE and WM_EXITSIZEMOVE on Windows and
XCB_CONFIGURE_NOTIFY on Linux XCB).

It worked OK, but recently there was some change ( at least on my NVidia card ) :
window resize causes vkQueuePresentKHR() function to return
VK_ERROR_OUT_OF_DATE_KHR before system event gets a chance to resize
swapchain images.
It means that instead of above mentioned system events I must use
vkGetPhysicalDeviceSurfaceCapabilitiesKHR() to obtain current swapchain image size.
OK, I can live with that.

But when I minimize my window - function vkCreateSwapchainKHR() returns ERROR_OUT_OF_DEVICE_MEMORY.
It turned out that when window is minimized then function vkGetPhysicalDeviceSurfaceCapabilitiesKHR()
returns VkSurfaceCapabilitiesKHR struct with currentExtent == {0,0}.

So I decided to define minimal size for swapchain images : {1,1}.
And now validation layer informs me that I cannot create such window,
because it’s bigger thanmaxImageExtent defined in VkSurfaceCapabilitiesKHR struct : {0,0}.
Deadlock.

Because of this - I decided to see how others implement window resizing.
And to my surprise - they don’t handle windows minimization either :

  • cube example from LunarG SDK halts infinitely when window is minimized
  • also examples written by Sascha Willems crash when window is minimized.
    I found that Sascha touched that issue ( 320 ), but left it opened.

My questions :

  1. since when vkQueuePresentKHR() and vkAcquireNextImageKHR() must use
    swapchain images with the same size as window size ?
    Is it defined somewhere in a specification ?
  2. If that change was added to specification:
    • what was the motivation ? Lack of WM_SIZE counterparts on some platforms ?
    • what should we do when window is minimized ?
  3. If it wasn’t added to specification - is it only NVidia specific ?

It’s a driver issue that’s still present in current drivers and not a problem with the implementation of e.g. my examples (works fine with other vendors). I reported it to nvidia some time ago but it seems they haven’t fixed it yet.

Which one issue we are discussing, because I wrote about two of them ?

First one is a demand that window size must be the same as swapchain image size
during vkQueuePresentKHR() and vkAcquireNextImageKHR() calls.

Second one is the impossibility to recreate swapchain images when window is minimized.

I’m talking about minimizung the window. Resizes work fine for me on multiple IHVs and platforms including nv.

Thank you for a clarification.
We will wait for a fix from NVidia then.

end of 2019 still no fix released yet ? i have the same issue with latest nvidia driver installed.

Can you reiterate what the perceived issue is specifically?

The stuff in OP seems app’s fault. It is app’s responsibility to handle VK_ERROR_OUT_OF_DATE (and any and all VkResults for that matter).

i fixed it with just stopping presentation and acquirement of the next image when the resize event of window comes with height=0 or width=0 or both 0ed(the latter is mostly caused by window minimization), all these cases will produce a bad extent .

Vulkan does not permit 0-sized swapchain.

That was a spec bug. It would break the object invariant that VkImage cannot be zero sized. It was fixed in spec some time ago.

you mean vkGetPhysicalDeviceSurfaceCapabilitiesKHR() should not return {0,0} extent ? i don’t really understand but the same issue described by pumex_lib is still present(you can’t create a swapchain bigger than the surface) and the strangest thing is that the surface capabilities min and max extent changes with window resize, maybe this is normal i don’t know. here is my specs:
vulkan version 1.1.126
os: windows
gpu : GTX 1070 with last nvidia update

No, the caps can return 0x0. That’s how you know the window is minimized or something. What I mean is, it is not permitted to vkCreateSwapchain with 0 extent.

Windows and X platforms always report min=current=max. That was always the case, and is even stated in the specification. The concept of min and max does not really naturally apply to these platforms. They are able to survive wrongly sized surface backing framebuffer out of necessity but the result was probably considered not graceful or even stable over the platform’s versions. So the spec wants you to steer into using currentExtent on those platforms.

so it is not a bug, you have to handle the minimization in the end.

Yes. It was a bug, but in the specification, not the driver.
The spec previously forgot to say 0-sized swapchain creation is not allowed. Though even then it made no sense if the reader paid attention – it would result in 0x0 VkImages which is not otherwisely allowed.

2 Likes

I’m currently affected by the very same bug, and I’m using the latest Nvidia driver available as of today ( 452.06 ). Indeed the very same code works fine on Intel. The Vulkan implementation I’m using comes from bgfx ( bgfx/renderer_vk.cpp at master · bkaradzic/bgfx · GitHub ).

Can anyone help me at least to figure out what is going on with this?