Why would vkCreateSwapchainKHR cause an access violation during swap chain re-creation irregularly? (Edit: regularly, namely exactly after 16 re-creations)

I am currently implementing swap chain re-creation after window-resize. I am using Vulkan-Hpp, so I am posting some rather Vulkan-Hpp-ish pseudocode. My basic approach is as follows:

try {
   Call to vk::Queue::presentKHR // this one throws an vk::OutOfDateKHRError exception
catch (vk::OutOfDateKHRError omg) {
    // recreating the swap chain
    vk::SwapchainCreateInfoKHR createInfo;
    createInfo.oldSwapchain = /* Passing the old, now out of date, swapchain handle */;
    /* All the other parameters of createInfo are set to the same values of the oldSwapchain */
    vk::Device::createSwapchainKHRUnique(createInfo); // Fails with access violation IRREGULARLY

createSwapchainKHRUnique sometimes causes an access violation while it works just fine most of the time. I.e. I try it ~20 times, it works ~19 times and fails ~1 time with the following error message:

Exception thrown at 0x00007FFED1D4A5C5 (nvoglv64.dll) in hello_world.exe: 0xC0000005: Access violation writing location 0x0000000000000038.

I don’t think that my general approach is wrong, otherwise it would not work at all. My question is: What could I be overlooking? Why would an access violation occur irregularly? What does it mean writing location 0x0000000000000038? => Can this be related to the swap chain images somehow? How could I narrow down the error?

I’ve also tried to put a vk::Device::waitIdle call right before the invocation of vk::Device::createSwapchainKHRUnique but that doesn’t help. Are there any good reference implementations for swap chain re-creation that use the createInfo.oldSwapchain parameter which I could have a look at?

Additional information:

This also happens with AMD GPUs and is pretty well reproducible:

Exception thrown at 0x00007FFF5E3D27F1 (amdvlk64.dll) in vulkan_tutorial.exe: 0xC0000005: Access violation reading location 0x000002016916EE90

The solution:

I did not clean up resources after creating the new swap chain: I did not destroy the old swap chain. I just thought: “I’ll implement clean-up later, after I have successfully tested that swap chain re-creation works.”. Turns out that there is an internal limit on the number of resources available for swap chains – or more precisely: how many swap chains can be created at the same time. Since that limit is 16 on both, NVIDIA and AMD, it might be that this limit comes from the VK_KHR_swapchain extension.

In short: Destroying the old swap chains with vkDestroySwapchainKHR solves the problem.

It’s just as likely a mechanism designed to catch when someone doesn’t clean up their resources :wink: This is in part why Windows forbids you from allocating more than 4096 pieces of GPU memory. Not because the hardware can’t handle it, but because if you do, that strongly suggests pathological behavior on the part of your program.