mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-27 00:28:14 +00:00
The recompiler orders an LDS atomic, and the compare-exchange loop that writes a byte or a halfword of LDS (ds_write_b8/b16), with a workgroup-scope OpMemoryBarrier after the update. AMD's proprietary Windows driver 32.0.21042.62 (Radeon 0x13c0, RDNA 2) compiles that memory barrier to s_barrier, as the code objects in its pipeline cache show. Such updates usually sit in branches that only some waves of a workgroup take, so those waves execute extra s_barriers, which pair with the other waves' barriers, and the other waves read LDS before it is written. An OpMemoryBarrier is not an execution barrier and SPIR-V allows it in non-uniform control flow, so the SPIR-V is valid; a device-scope OpMemoryBarrier compiles to GL0 and GL1 cache invalidations without s_barrier there. PS5LM Plus (PPSA99581, llama.cpp's Vulkan backend) drifted into garbage on that driver with flash attention on. Its flash-attention shader stores two halfwords to LDS in a branch that two of its four waves take, inside the KV loop. The driver's code had 23 s_barrier for the guest's 21; a replay of the dispatch differed from NVIDIA in 159 words, up to 1.7e38, and now has 21 and differs only in the last bit of 9 words. On that driver the fence is now device scope, which orders everything the workgroup-scope fence did. Other drivers keep the workgroup scope. The flag is part of the shader cache key, and agc_shader_replay takes --device-scope-lds-memory-barriers to replay a request the way that driver compiles it. The LDS update helper already fences, so the second, identical fence after it in ds_min/max_f32 and the other read-modify-write LDS operations is dropped. agc_driver_lds_subword_store_branch stores a halfword to LDS in a branch that waves 0-1 of four take, delays those waves and then exchanges LDS slots across one s_barrier. Before, thread 64 read a stale slot on the AMD driver; it passes on AMD and NVIDIA now. agc_subgroup_barrier checks the driver quirk and that ds_write_b16, ds_add_u32 and ds_max_f32 each emit one fence of the expected scope. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01BM2kfDbr6MydxsfTckZJDR