diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-30 11:57:48 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-11-01 11:05:53 -0500 |
| commit | 6e38b4c8fbb653eef82864a76127f04f4da4c394 (patch) | |
| tree | e4cb15451d8982d0bd74505af2d9347e87ae84e6 /src | |
| parent | d88554cedb396863929dd31439dc8d4c92b367c8 (diff) | |
nx2: lower REDUX.OR and REDUX.XOR
The warp reduction was lowered for SUM and unsigned MAX; Kirby Air Riders
reduces with OR. Inactive lanes contribute zero, as for the sum, so OR
and XOR accumulate with LOP over the same 32-lane walk.
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/frontend/ampere/lower_to_maxwell.h | 9 |
1 files changed, 7 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 b59118efa3..d81f6742b1 100644 --- a/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h +++ b/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h @@ -860,11 +860,13 @@ inline LoweredProgram LowerToMaxwell(std::span<const Instruction> code) { restore_predicate(); break; } - case 0x3c4: { // REDUX.SUM (modulo 2^32) or .MAX (unsigned) over the actual active lanes. + case 0x3c4: { // REDUX.SUM (modulo 2^32), .MAX (unsigned), .OR or .XOR over the actual active lanes. const u32 source = insn.Bits(24, 8), target = uniform_register(static_cast<u32>(dest)); const bool maximum = insn.words[2] == 0x14000; + // OR and XOR: inactive lanes contribute zero, as for the sum. Maxwell LOP: 1 = OR, 2 = XOR. + const u32 logical = insn.words[2] == 0x4000 ? 1U : insn.words[2] == 0x8000 ? 2U : 0U; if (target == ~0U || target == 255 || insn.words[1] || - (insn.words[2] != 0xc000 && !maximum) || native_predicate != 7) + (insn.words[2] != 0xc000 && !maximum && !logical) || native_predicate != 7) return fail(index, "native warp sum mode"); emit(0x50d8000000070000ULL | 250 | (u64{7} << 39) | (u64{7} << 45) | (u64{1} << 48)); mov_imm(target, 0); @@ -877,6 +879,9 @@ inline LoweredProgram LowerToMaxwell(std::span<const Instruction> code) { emit(0x5c40000000070000ULL | 251 | (u64{251} << 8) | (u64{252} << 20) | (u64{7} << 48)); if (maximum) { emit(0x5c20000000070000ULL | target | (u64{target} << 8) | (u64{251} << 20) | (u64{15} << 39)); + } else if (logical) { + emit(0x5c40000000070000ULL | target | (u64{target} << 8) | (u64{251} << 20) | + (u64{logical} << 41) | (u64{7} << 48)); } else { emit(0x5c10000000070000ULL | target | (u64{target} << 8) | (u64{251} << 20)); } |
