From fa3a5ec67ef73e4bc022f65aefe18de1f893d0a3 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 18 Mar 2026 02:20:35 -0700 Subject: [PATCH] fix: correct water refraction barrier srcAccessMask to prevent VK_ERROR_DEVICE_LOST MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The captureSceneHistory barrier was using srcAccessMask=0 with VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT when transitioning the swapchain image from PRESENT_SRC_KHR to TRANSFER_SRC_OPTIMAL. This does not flush the GPU's color attachment write caches, causing VK_ERROR_DEVICE_LOST on strict drivers (AMD, Mali) that require explicit cache invalidation before transfer reads. Fix: use VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT + COLOR_ATTACHMENT_OUTPUT as the source mask so color writes are properly made visible to the transfer unit before the image copy begins. Also remove the now-unnecessary "requires FSR" restriction in the settings UI — water refraction can be enabled independently of FSR. --- src/rendering/water_renderer.cpp | 8 ++++++-- src/ui/game_screen.cpp | 11 ++--------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/rendering/water_renderer.cpp b/src/rendering/water_renderer.cpp index 2bbff1a3..6dd0b26f 100644 --- a/src/rendering/water_renderer.cpp +++ b/src/rendering/water_renderer.cpp @@ -1142,10 +1142,14 @@ void WaterRenderer::captureSceneHistory(VkCommandBuffer cmd, }; // Color source: final render pass layout is PRESENT_SRC. + // srcAccessMask must be COLOR_ATTACHMENT_WRITE (not 0) so that GPU cache flushes + // happen before the transfer read. Using srcAccessMask=0 with BOTTOM_OF_PIPE + // causes VK_ERROR_DEVICE_LOST on strict drivers (AMD/Mali) because color writes + // are not made visible to the transfer unit before the copy begins. barrier2(srcColorImage, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - 0, VK_ACCESS_TRANSFER_READ_BIT, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); barrier2(sh.colorImage, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 712488cf..3c39bba3 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -15928,18 +15928,11 @@ void GameScreen::renderSettingsWindow() { } } { - bool fsrActive = renderer && (renderer->isFSREnabled() || renderer->isFSR2Enabled()); - if (!fsrActive && pendingWaterRefraction) { - // FSR was disabled while refraction was on — auto-disable - pendingWaterRefraction = false; - if (renderer) renderer->setWaterRefractionEnabled(false); - } - if (!fsrActive) ImGui::BeginDisabled(); - if (ImGui::Checkbox("Water Refraction (requires FSR)", &pendingWaterRefraction)) { + if (ImGui::Checkbox("Water Refraction", &pendingWaterRefraction)) { if (renderer) renderer->setWaterRefractionEnabled(pendingWaterRefraction); + updateGraphicsPresetFromCurrentSettings(); saveSettings(); } - if (!fsrActive) ImGui::EndDisabled(); } { const char* aaLabels[] = { "Off", "2x MSAA", "4x MSAA", "8x MSAA" };