From 96ff2bd8839d648c3e0b3a09aeead80aef4569e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 19 Oct 2026 07:47:48 +0200 Subject: [PATCH] Don't draw a frame from RAM outside the backbuffer pass after toggling Skip Buffer Effects The GPU only picks up the setting when emulation runs, so after turning Skip Buffer Effects off in the pause menu, PreRender ran the buffered-mode display path with a GPU still in non-buffered mode. For a frame displayed from RAM, that draws straight to output (since b8789af997) with no render pass bound, crashing in VulkanRenderManager::SetScissor. Co-Authored-By: Claude Opus 5.5 (1M context) --- UI/EmuScreen.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index ffbca45789..397b5734cd 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -61,6 +61,7 @@ using namespace std::placeholders; #include "Core/Reporting.h" #include "Core/Util/PathUtil.h" #include "Core/System.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/PresentationCommon.h" #include "GPU/GPUState.h" #include "GPU/GPUCommon.h" @@ -1601,6 +1602,14 @@ bool EmuScreen::ShouldRunEmulation(ScreenRenderMode mode) const { return true; } +// The GPU only picks up a changed Skip Buffer Effects setting in BeginHostFrame, so while emulation +// isn't running (like in the pause menu) it can still be in non-buffered mode. There, it draws straight +// into the backbuffer pass, which isn't bound yet in PreRender. +static bool GPUIsBuffered() { + FramebufferManagerCommon *framebufferManager = gpu->GetFramebufferManagerCommon(); + return !framebufferManager || framebufferManager->UseBufferedRendering(); +} + ScreenRenderFlags EmuScreen::PreRender(ScreenRenderMode mode) { // If a boot is in progress, update it. ProcessGameBoot(gamePath_); @@ -1611,7 +1620,7 @@ ScreenRenderFlags EmuScreen::PreRender(ScreenRenderMode mode) { if (ShouldRunEmulation(mode)) { // We need to run emulation here, and perform all the normal render passes. return RunEmulation(false); - } else if (gpu) { + } else if (gpu && GPUIsBuffered()) { // Need to check for gpu here, we might be in reset. const DeviceOrientation orientation = GetDeviceOrientation(); const DisplayLayoutConfig &displayLayoutConfig = g_Config.GetDisplayLayoutConfig(orientation);