Repository navigation
fix(shader): mask EXEC copies to the host subgroup's lanes - #1264
Conversation
A wave64 graphics program on a 32-lane host runs one guest lane per invocation, yet an EXEC written as a value keeps all 64 bits: the NGG prologue's s_lshr_b64 exec, -1, 64 - count reads count 0 and sets -1. A waterfall loop that copies EXEC with s_mov_b64 and retires one key per pass then never empties its copy, since no ballot sets the lanes the host lacks, and its v_readlane picks lane 32 and up. readRawU32 now ANDs EXEC with a ballot of true when it is read as a value (s_mov_b64, ALU sources, src_execz), and s_*_saveexec and s_*_wrexec store that masked copy. EXEC's own words, threadBit and the saveexec combination keep the raw words, so s_orn2_saveexec_b64 vcc, exec still sets all 64 bits. On subgroups under 32 lanes the EXEC_LO copies of agc_driver_scalar_sop1 now hold only the subgroup's lanes.
|
Tested on Linux and an AMD host, both listed as not tested. Nobara 44 (Linux 7.2), GCC 16.2.1, Release,
|
|
Thanks for running this on the 7600X. A 64-lane pixel subgroup is the case I can't reach on my NVIDIA laptop, so it's good to see |
|
Checked: merged onto current |
What
On a 32-lane host, wave64 graphics stages run one guest lane per invocation, but an EXEC written as a value still has bits for lanes 32-63. An
s_mov_b64copy of it keeps lanes no ballot clears, so a waterfall loop over the copy never ends.readRawU32reads EXEC as EXEC & ballot(true) (hostExecWord) fors_mov_b64 sN, exec, ALU sources and EXECZ, ands_*_saveexecands_*_wrexecstore that copy. EXEC's own words,threadBitand the saveexec combination stay raw, sos_orn2_saveexec_b64 vcc, execstill sets all 64 bits.agc_driver_scalar_sop1masks its EXEC_LO copies there. TechnicalDebt notes the console's EXEC holds the other lanes too.s_lshr_b64 exec, -1, 64 - countsets EXEC to -1. With our pending null-SRT work those draws run and hung the GPU at about 695 s. Under a 65,536-pass loop guard only these two shaders tripped it (102 times in 2,700 s).TranslationContext.hppwithout conflicting.Tested
mainc5e1018: configure-DBUILD_TESTING=ON, full build,--target libs,ctest:ctest --output-on-failure)VK_DRIVER_FILES): 395/395 pass;agc_driver_flat_storeis left out there because it takes several minutes on Windows llvmpipeagc_driver_exec_host_lanes: the title's loop (loads cut to ones_buffer_load_dword, capped at 128 passes) takes at most 6 passes in a 189-vertex wave64 draw (32+ lanes) and a 192-thread wave64 dispatch. It fails onmainwith 128: the draw on NVIDIA, the dispatch on llvmpipe.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)