Single VkDevice, multiple windows: the 2nd swapchain fails with "internal drawable creation failed"


I’m working on an application that wants to create multiple windows, but keep all graphics resources (textures, buffers, etc) shared between them.
Obviously, resources specific to each window (such as the swapchain, sync objects for the swapchain, etc) would remain per-window and not be shared.

I know it’s doable in general, because Unreal Engine’s editor supports it (you can drag an editor tab outside of the current window, and it will create a new one; I’m pretty sure it does not duplicate all graphics resources in doing so).

So I have designed my application as follows:

  • 1 VkInstance;
  • 1 VkDevice (owner of all textures and buffers);
  • N “windows”, each window consisting of: surface + swapchain + swapchain image views + sync objects for the swap chain, etc.

Whenever I create a new window and its surface, I check that the physical device for my existing windows (if any) is suitable for that new surface. From that, I conclude that the single VkDevice I’ve created can be used for that window, as long as I create a new swapchain for it and do not interfere with the swapchain of other windows.

In the case of a single window, everything works as expected.

But when I create a second window (including its surface and swapchain), on the same VkDevice:

  • I get the validation error “vkCreateSwapchainKHR: internal drawable creation failed”.
  • The swapchain of the first window is invalidated, despite the fact that these are two different surfaces.

Because swapchains seem to be designed to be “per-surface” rather than “per-device”, and because I think very few people seem to attempt this, I am assuming that either :

  • It is a driver bug that assumes there can be only one swapchain per VkDevice;
  • My design is wrong and there’s something I’m not doing correctly.

I would really appreciate if someone with knowledge of the drivers could confirm this, i.e look at the swapchain creation code and see whether it assumes 1 swapchain per device.

Failing that, is there some way of easily sharing resources between multiple VkDevices ? If so, I could attempt one VkDevice per window (same phys. device).

Thank you very much.

So in the end I found the fix: it’s just that I’m using vk-bootstrap, and it is caching the first surface into its device wrapper.

It turns out that all along, the code was passing the first surface (instead of the second one) for creation of the second swapchain, so we end up with two swapchains for the first surface, which explains everything.

The fix was to manually set the “surface” member in the vkb::Device and vkb::PhysicalDevice structs before of all of the swapchain creation logic.