From 802c8fc6e4a3324bda2224c4ca2737e97121b80f Mon Sep 17 00:00:00 2001 From: kuba Date: Sat, 3 Oct 2026 23:24:52 +0200 Subject: [PATCH] [SpirvTranslator] Keep wave64 LDS phase barriers when a half-mask plan applies The half-mask plan's barriers order its own mask exchanges, not the program's shared-memory traffic, yet planning a program switched the LDS phase ordering off. UE's FFT bloom (wave64, 512 threads, LDS butterflies) then read half-written rows: Silent Hill's convolution output collapsed into a flat haze (max 56 for a scene peaking above 1500) and the histogram fed by it never adapted exposure. --- src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs index 9eec5ba..f204501 100644 --- a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs +++ b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs @@ -1453,9 +1453,11 @@ public static partial class Gen5SpirvTranslator var block = blocks[blockIndex]; var halfMaskPlan = HalfMaskPlan(); // One guest wave can span two host subgroups. Keep its shared-memory phases ordered. - // The half-mask plan inserts its own barriers; other wave64 programs also - // need LDS phase ordering when reads and writes span basic blocks. - var synchronizeSharedMemory = _emulateWave64 && halfMaskPlan is null; + // The half-mask plan's barriers only order its own mask exchanges, not the program's + // LDS traffic: with phase ordering off under the plan, UE's FFT bloom (wave64, 512 + // threads, LDS butterflies) read half-written rows and blurred Silent Hill's whole + // post chain into a flat haze. + var synchronizeSharedMemory = _emulateWave64; var sharedMemoryPhase = SharedMemoryPhase.None; for (var index = block.StartIndex; index < block.EndIndex; index++) {