From f6e70b88ad7937fe5782539f5235059c09ba2f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2026 14:05:00 -0600 Subject: [PATCH] Headless: Take the timeout screenshot before ending the draw frame On Vulkan, reading back the display framebuffer after EndDrawFrame hit the insideFrame_ assert in CopyFramebufferToMemory, so any run that timed out with --screenshot-save crashed in debug builds. Co-Authored-By: Claude Opus 5.5 (1M context) --- headless/Headless.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/headless/Headless.cpp b/headless/Headless.cpp index df38b243ed..b7adf0eb9e 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -515,6 +515,13 @@ static bool RunAutoTest(GraphicsContext *graphicsContext, CoreParameter &corePar gpu->EndHostFrame(); } + // Before EndDrawFrame: Vulkan can only read back a framebuffer inside a frame. + if (!g_screenshotSavePath.empty() && !g_screenshotSaved) { + // SendDebugScreenshot ignores the descriptor and reads the display framebuffer from the GPU + // itself, so there's nothing to fill in here. + SendDebugScreenshot(DebugScreenshotDesc{}); + } + if (draw) { // Vulkan may get angry if we don't do a final present. if (gpu) { @@ -527,12 +534,6 @@ static bool RunAutoTest(GraphicsContext *graphicsContext, CoreParameter &corePar EndDrawFrame(draw); } - if (!g_screenshotSavePath.empty() && !g_screenshotSaved) { - // SendDebugScreenshot ignores the descriptor and reads the display framebuffer from the GPU - // itself, so there's nothing to fill in here. - SendDebugScreenshot(DebugScreenshotDesc{}); - } - PSP_Shutdown(true); if (!opt.bench) {