From 82a5b520bc6dc4a77acca9b3ddd0bc577ada5676 Mon Sep 17 00:00:00 2001 From: Takoroka <137927095+Takoroka@users.noreply.github.com> Date: Wed, 28 Oct 2026 15:44:48 -0400 Subject: Switch 2 shaders: MUFU.SIN/COS take turns, Eden's Maxwell MUFU radians SM70+ removed RRO: compilers multiply the angle by 1/2pi (FMUL.RZ by 0.15915494) and MUFU.SIN/COS compute sin/cos(2pi x). Eden's Maxwell MUFU computes sin/cos of radians (its RRO is a plain move), so every lowered sine and cosine used the wrong angle (wind animation, rotations, the ocean FFT twiddles). Scale the operand by 2pi first. --- src/shader_recompiler/frontend/ampere/lower_to_maxwell.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h b/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h index 1390951ef5..365efa1118 100644 --- a/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h +++ b/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h @@ -1732,16 +1732,26 @@ inline LoweredProgram LowerToMaxwell(std::span code) { case 0x308: case 0xb08: { // MUFU const u32 operation = insn.Bits(74, 6); if (operation > 8 || operation == 6 || operation == 7 || insn.Bits(80, 12)) return fail(index, "native MUFU mode"); + // SM70+ MUFU.COS/SIN take the angle in turns (compilers multiply by 1/2pi first); + // Eden's Maxwell MUFU takes radians (its RRO is a plain move), so scale by 2pi. + const bool turns = operation == 0 || operation == 1; + const auto to_radians = [&](u32 source) { + emit(0x1e00000000000000ULL | predicate | 250 | (u64{source} << 8) | + (u64{0x40c90fdbU} << 20)); + return 250U; + }; if (insn.Bits(73, 1)) { if (opcode != 0x308 || insn.Bits(60, 2) > 1) return fail(index, "native half special-function source"); emit(0x5ca8000000000000ULL | predicate | 250 | (u64{2} << 8) | (u64{1} << 10) | (u64{insn.Bits(32, 8)} << 20) | (u64{insn.Bits(60, 1)} << 41) | (u64{insn.Bits(63, 1)} << 45) | (u64{insn.Bits(62, 1)} << 49)); + if (turns) to_radians(250); emit(0x5080000000000000ULL | predicate | 250 | (u64{250} << 8) | (u64{operation} << 20)); emit(base(0x5ca8000000000000ULL) | (u64{1} << 8) | (u64{2} << 10) | (u64{250} << 20)); } else { - const u32 src = operand(1); + u32 src = operand(1); + if (turns) src = to_radians(src); emit(base(0x5080000000000000ULL) | (u64{src} << 8) | (u64{operation} << 20)); } break; -- cgit v1.2.3