diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-30 11:46:42 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-11-01 11:05:48 -0500 |
| commit | 567aaa3e88244162c083bc525f13db40cdd2cce1 (patch) | |
| tree | 7beaa65b0f9e2dacc588851a9ee1a134525eb01b | |
| parent | fa1f6b1d7ba4f880821802f88fe48cd9d01e1f50 (diff) | |
nx2: lower 32-bit MATCH.ALL
Only MATCH.ALL.U64 was lowered; Nintendo Switch Sports Resort and Kirby
Air Riders use the 32-bit form (MATCH.ALL P0, RZ, Rx) in compute and
pixel shaders. Compare one word instead of two.
| -rw-r--r-- | src/shader_recompiler/frontend/ampere/lower_to_maxwell.h | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h b/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h index 4cc2d0eb84..9a5b55033b 100644 --- a/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h +++ b/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h @@ -836,23 +836,26 @@ inline LoweredProgram LowerToMaxwell(std::span<const Instruction> code) { emit(0x3828000000000000ULL | predicate | (dest + 216) | (u64{insn.words[1] + 216} << 8) | (u64{1} << 39) | (u64{1} << 40)); break; - case 0x3a1: { // MATCH.ALL.U64 with only the all-equal predicate retained. + case 0x3a1: { // MATCH.ALL (.U32, or .U64 on bit 73) with only the all-equal predicate retained. const u32 source = insn.Bits(24, 8), target = insn.Bits(81, 3); - if (dest != 255 || source >= 254 || (source & 1) || target >= 6 || - native_predicate != 7 || insn.words[1] || (insn.words[2] & ~0xe0000U) != 0x200) + const u32 words = insn.Bits(73, 1) ? 2 : 1; + if (dest != 255 || source >= 254 || (words == 2 && (source & 1)) || target >= 6 || + native_predicate != 7 || insn.words[1] || (insn.words[2] & ~0xe0200U) != 0) return fail(index, "native warp match mode"); save_predicate(); + // Compare every lane with the lowest active one, then require all to agree. emit(0x50d8000000070000ULL | 250 | (u64{7} << 39) | (u64{7} << 45) | (u64{1} << 48)); emit(0x5c10000000070000ULL | 251 | (u64{250} << 8) | (u64{255} << 20) | (u64{1} << 49)); emit(0x5c40000000070000ULL | 250 | (u64{250} << 8) | (u64{251} << 20) | (u64{7} << 48)); emit(0x5c30000000070000ULL | 250 | (u64{250} << 20)); - for (u32 word = 0; word < 2; ++word) + for (u32 word = 0; word < words; ++word) emit(0xef10000000070000ULL | (251 + word) | (u64{source + word} << 8) | (u64{250} << 20) | (u64{1} << 29) | (u64{31} << 34) | (u64{7} << 48)); emit(0x5b60000000070000ULL | 7 | (u64{6} << 3) | (u64{source} << 8) | (u64{251} << 20) | (u64{7} << 39) | (u64{2} << 49)); - emit(0x5b60000000070000ULL | 7 | (u64{6} << 3) | (u64{source + 1} << 8) | - (u64{252} << 20) | (u64{6} << 39) | (u64{2} << 49)); + if (words == 2) + emit(0x5b60000000070000ULL | 7 | (u64{6} << 3) | (u64{source + 1} << 8) | + (u64{252} << 20) | (u64{6} << 39) | (u64{2} << 49)); emit(0x50d8000000070000ULL | 255 | (u64{6} << 39) | (u64{target} << 45)); restore_predicate(); break; |
