diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-30 12:18:10 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-11-01 11:08:18 -0500 |
| commit | fdca67d7312ca371a63a0941af05b7c2e33b5b59 (patch) | |
| tree | f9ebe287e8ff0868b4ce8df778c08c2132bea0ea /src/shader_recompiler | |
| parent | 716539186becf44de19117614c2b428bb53aeb85 (diff) | |
nx2: lower LDC.IS, constant loads with segmented addressing
LDC was lowered only in its default mode; Kirby Air Riders' main vertex
shader loads with LDC.64.IS (Ra + offset addressing all constant buffers
as one space, the buffer in the high half), so every draw using it was
skipped and the screen stayed black. Bits 78-79 hold the mode numbered as
Maxwell LDC's (44-45, 2 = IS), which Eden's Maxwell LDC implements.
Diffstat (limited to 'src/shader_recompiler')
| -rw-r--r-- | src/shader_recompiler/frontend/ampere/lower_to_maxwell.h | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h b/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h index 290ab5c9c4..2a33c2dd1e 100644 --- a/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h +++ b/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h @@ -753,13 +753,15 @@ inline LoweredProgram LowerToMaxwell(std::span<const Instruction> code) { (u64{(high_result ? high : low) + 216} << 8) | (u64{insn.words[1]} << 20)); break; } - case 0xb82: { // LDC.64 indexed byte offset - const u32 width = insn.Bits(73, 3); - if ((width != 4 && width != 5) || insn.Bits(78, 2) || insn.Bits(91, 1) || + case 0xb82: { // LDC.64 indexed byte offset; bits 78-79 the mode as Maxwell's (2 = IS) + // .IS: Ra + offset addresses all constant buffers as one space, the buffer in its high + // half (Kirby Air Riders' vertex shaders), which Eden's Maxwell LDC implements. + const u32 width = insn.Bits(73, 3), mode = insn.Bits(78, 2); + if ((width != 4 && width != 5) || (mode != 0 && mode != 2) || insn.Bits(91, 1) || bank() >= 18 || (width == 5 && ((dest & 1) || dest >= 254))) return fail(index, "native indexed constant load mode"); emit(base(0xef90000000000000ULL) | (u64{insn.Bits(24, 8)} << 8) | - (u64{insn.Bits(38, 16)} << 20) | (u64{bank()} << 36) | (u64{width} << 48)); + (u64{insn.Bits(38, 16)} << 20) | (u64{bank()} << 36) | (u64{mode} << 44) | (u64{width} << 48)); break; } case 0xf89: { // SHFL with immediate lane and segmentation/clamp mask, any mode. |
