Skip to content

Alternative swapchain model #2863

Closed
@kvark

Description

@kvark

Situation

We have a lot of swapchain-related issues:

  • it doesn't map to Metal:
    • the current solution is hacky and occasionally fires back, with things like full-screen, or orientation change on iOS
  • it doesn't map to most GL WSI
    • GL doesn't let you us VkImage of the framebuffer, although may be possible in some configurations (i.e. Wayland, or IOSurface-backed WSI)
  • it doesn't map nice to DX12
    • users aren't allowed to do anything with any other image than currently acquired

it's really the most rough API piece of all the things we have... and the problem comes from how Vulkan exposes the swapchain. Good thing is - designers of Vulkan anticipated the WSI being the pain spot and excluded it from the core specification.

Idea

What if we expose a very simple (and limited) API for the swapchain: you get the next frame as as a structure that can be borrowed as Framebuffer, you draw to it (only using one-time-submit command buffers), and you pass it back by value on present(). That's it. No enumeration of images ahead of time, no semaphores, less possible errors on the way and definitely less pain for the backends to implement it.

My bet is that this simple model would work for most of the client apps. I'd like to hear from our users if it wouldn't work. The only known use that doesn't it this scenario is gfx-portability... so my hope is to structure that simple API in such a way that the current complex logic of Metal backend (mapping Vulkan to Metal) is basically moved and adopted there, in gfx-portability. It could in fact even be simpler since at this level we have the leverage of providing more hidden state info from the backends.

Note: having render-only swapchain images is certainly more limited than regular Vulkan WSI, where you could ask for supported usages and potentially copy to/from the swapchain images, even bind them as storage, etc. However, there is evidence that presentation works most efficiently if it's only rendered to: Metal has a special flag "isFramebufferOnly" indicating possible optimizations, and DXGI is known to operate in a different mode if you need readbacks and such.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions