thin3d: Swapchain objects, and multiple swapchains on Metal

The backbuffer is now a Swapchain, from GetPrimarySwapchain(), and
callers bind, measure and read it back through that instead of nullptr.
nullptr still means it too. Backends with one swapchain map the primary
to their old backbuffer path.

On Metal, CreateSwapchain() adds more, each with its own layer, depth
buffer and drawable. Passes merge per swapchain, and Present() presents
every drawable acquired that frame. The backbuffer is just the first
of them. Nothing creates a second one yet.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-22 18:42:53 +02:00
1 parent 26e302aa86
commit 56c76ace35
14 files changed
+336 -156

No files matched your search

+2 -2
View File
@@ -212,8 +212,8 @@ ScreenRenderFlags ScreenManager::Render(std::function<void()> afterPreRender) {
afterPreRender();
// Now, start the final render pass. This is now the ONLY place where binding the null fb is allowed.
draw_->BindFramebufferAsRenderTarget(nullptr, {RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR}, "BackBuffer");
// Now, start the final render pass. This is now the ONLY place where binding the backbuffer is allowed.
draw_->BindFramebufferAsRenderTarget(draw_->GetPrimarySwapchain(), {RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR}, "BackBuffer");
getUIContext()->BeginFrame();
const Draw::Viewport viewport{0.0f, 0.0f, (float)g_display.pixel_xres, (float)g_display.pixel_yres, 0.0f, 1.0f};