diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-31 16:03:15 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-31 16:03:15 -0400 |
| commit | 77ea16e2f26edb443341a12e8169018fc1fa648e (patch) | |
| tree | e836c97c493643a0efb3e97ece75e46d65e2f30e /src | |
| parent | 9dca3ab2e436e786ab53e862e4d515f620a11669 (diff) | |
nx2: drop R2UR's unreachable keep-old-value select when unpredicated
R2UR was lowered as "the value of the first lane in the ballot, else the
uniform register's old value". With no execution predicate the ballot always
holds the executing lane, so the fallback is never taken, but it stayed in the
program as a second source of the result. The texture handle search found it
first: in Switch Sports the uniform register had just held a storage buffer
pointer loaded from the constant buffer, so the scenery's texture handle was
traced to that pointer word instead of to the value the shader moved in.
Write the broadcast value directly when the instruction is unpredicated.
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/frontend/ampere/lower_to_maxwell.h | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h b/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h index 031f7fac75..6bc07638ea 100644 --- a/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h +++ b/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h @@ -614,8 +614,15 @@ inline LoweredProgram LowerToMaxwell(std::span<const Instruction> code) { emit(0x5c30000000070000ULL | 250 | (u64{250} << 20)); emit(0xef10000000070000ULL | 251 | (u64{insn.Bits(24, 8)} << 8) | (u64{250} << 20) | (u64{1} << 29) | (u64{31} << 34) | (u64{7} << 48)); - emit(0x5ca0000000070000ULL | target | (u64{251} << 8) | - (u64{target} << 20) | (u64{6} << 39)); + if (native_predicate == 7) { + // Every lane executing it is in the ballot, so no lane-less fallback can be taken. + // Leaving the old value selectable would make it a source of the result for the + // texture and global memory tracking (a handle traced to the uniform's last load). + emit(0x5c98000000070000ULL | target | (u64{15} << 39) | (u64{251} << 20)); + } else { + emit(0x5ca0000000070000ULL | target | (u64{251} << 8) | + (u64{target} << 20) | (u64{6} << 39)); + } restore_predicate(); break; } |
