From eccb320287b3d02f0ae258385100b52888e69db1 Mon Sep 17 00:00:00 2001 From: jpolo1224 Date: Wed, 1 Jul 2026 11:55:02 -0400 Subject: [PATCH] GS/Vulkan: atomic pipeline-cache write to prevent corruption on kill --- .../cpp/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ARMSX2/app/src/main/cpp/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp b/ARMSX2/app/src/main/cpp/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp index c11501f8e0..561d5d0dab 100644 --- a/ARMSX2/app/src/main/cpp/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp +++ b/ARMSX2/app/src/main/cpp/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp @@ -616,9 +616,17 @@ bool VKShaderCache::FlushPipelineCache() if (!FileSystem::StatFile(m_pipeline_cache_filename.c_str(), &sd) || sd.Size != static_cast(data_size)) { Console.WriteLn("Writing %zu bytes to '%s'", data_size, m_pipeline_cache_filename.c_str()); - if (!FileSystem::WriteBinaryFile(m_pipeline_cache_filename.c_str(), data.data(), data.size())) + // @@ARMSX2_VKCACHE_ATOMIC@@ Stage to a temp file then rename over the real one. A swipe-kill + // or crash mid-write otherwise leaves a half-written pipeline cache that some drivers (Adreno) + // still accept past the header check and then render garbage from — the "corrupt VK cache" + // bug that manifested as dark/purple textures until the cache was manually cleared. rename() + // is atomic on POSIX, so the previous valid cache survives a failed/interrupted write. + const std::string tmp_filename = m_pipeline_cache_filename + ".tmp"; + if (!FileSystem::WriteBinaryFile(tmp_filename.c_str(), data.data(), data.size()) || + !FileSystem::RenamePath(tmp_filename.c_str(), m_pipeline_cache_filename.c_str())) { Console.Error("Failed to write pipeline cache to '%s'", m_pipeline_cache_filename.c_str()); + FileSystem::DeleteFilePath(tmp_filename.c_str()); return false; } }