diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-30 11:57:50 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-11-01 11:08:07 -0500 |
| commit | b52f29993f4a9b18b153860fb3da8ef7db73eaf2 (patch) | |
| tree | 4f1304dfcab909fcb3996c5f6988bd465645214c /src | |
| parent | 572c89d7134691a36395cd469dc89b4ae0924fc1 (diff) | |
nx2: lower CSMTEST as a false test
Kirby Air Riders' vertex-side shaders run CSMTEST, a test of shading-mode
state Eden does not model, then exit early when it holds ("CSMTEST.A.
FCSM_TR P0; @P0 EXIT"); another discards its result. Set its predicate
outputs to false, so these shaders run through instead of being rejected.
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/frontend/ampere/lower_to_maxwell.h | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h b/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h index a982312ae9..a7800bdea1 100644 --- a/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h +++ b/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h @@ -860,6 +860,18 @@ inline LoweredProgram LowerToMaxwell(std::span<const Instruction> code) { restore_predicate(); break; } + case 0x80d: { // CSMTEST: a test of shading-mode state Eden does not model, taken as false. + // Kirby Air Riders' vertex-side shaders run "CSMTEST.A.FCSM_TR P0" then "@P0 EXIT": + // never leave early. Outputs of PT discard the result. + const u32 first = insn.Bits(81, 3), second = insn.Bits(84, 3); + if (insn.Bits(87, 4) != 7 || insn.Bits(16, 16)) + return fail(index, "native CSM test mode"); + for (const u32 target : {first, second}) + if (target != 7) + emit(0x5090000000000000ULL | predicate | (u64{target} << 3) | 7 | (u64{7} << 12) | + (u64{1} << 15) | (u64{7} << 29) | (u64{7} << 39)); + break; + } 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; |
