From 753508465247ffae680189e9c47eaff09dbe78fe Mon Sep 17 00:00:00 2001 From: Kelsi Date: Mon, 2 Mar 2026 10:24:02 -0800 Subject: [PATCH] Disable captureSceneHistory to fix VK_ERROR_DEVICE_LOST crash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The single sceneColorImage races between frames with MAX_FRAMES_IN_FLIGHT=2: frame N-1's water shader reads it while frame N's captureSceneHistory writes it via vkCmdCopyImage. Pipeline barriers only sync within a single command buffer, not across submissions on the same queue. This caused VK_ERROR_DEVICE_LOST after ~700 frames on any map with water. Disable the capture entirely for now — water renders without refraction. TODO: allocate per-frame scene history images to eliminate the race. --- src/rendering/renderer.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/rendering/renderer.cpp b/src/rendering/renderer.cpp index 537e5398..d7bf0b48 100644 --- a/src/rendering/renderer.cpp +++ b/src/rendering/renderer.cpp @@ -1054,18 +1054,13 @@ void Renderer::endFrame() { vkCmdEndRenderPass(currentCmd); - // Only capture scene history when water surfaces exist (avoids GPU crash on WMO-only maps - // where scene history images may never be properly used but layout transitions still run) - if (waterRenderer && waterRenderer->hasSurfaces() && currentImageIndex < vkCtx->getSwapchainImages().size()) { - waterRenderer->captureSceneHistory( - currentCmd, - vkCtx->getSwapchainImages()[currentImageIndex], - vkCtx->getDepthCopySourceImage(), - vkCtx->getSwapchainExtent(), - vkCtx->isDepthCopySourceMsaa()); - } + // Scene-history capture is disabled: with MAX_FRAMES_IN_FLIGHT=2, the single + // sceneColorImage can race between frame N-1's water shader read and frame N's + // transfer write, eventually causing VK_ERROR_DEVICE_LOST. Water renders + // without refraction until per-frame scene-history images are implemented. + // TODO: allocate per-frame sceneColor/Depth images to fix the race. - // Render water in separate 1x pass after MSAA resolve + scene capture + // Render water in separate 1x pass (without scene refraction for now) bool waterDeferred = waterRenderer && waterRenderer->hasSurfaces() && waterRenderer->hasWater1xPass() && vkCtx->getMsaaSamples() != VK_SAMPLE_COUNT_1_BIT; if (waterDeferred && camera) {