aboutsummaryrefslogtreecommitdiff
path: root/src/shader_recompiler
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-30 14:30:08 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-11-01 11:09:50 -0500
commita08454340e52fde44dc13f9ab585f21e0c463f50 (patch)
treec7e6809f5126fd39c9a55b2690be36862281eb97 /src/shader_recompiler
parent563ed8e60b0dd053ac8017aafa2f78c78747600b (diff)
nx2: lower TEX.B with an explicit LOD
Kirby Air Riders samples a cube texture at an explicit level through a bindless handle (TEX.B.LL R20, R16, R12, R16, CUBE): the coordinates stay in Ra (R12-R14) and Rb holds the handle, then the LOD (R16, R17), since five values do not split evenly. Place the values that way and take .LL and .LB (the bias in the LOD's place).
Diffstat (limited to 'src/shader_recompiler')
-rw-r--r--src/shader_recompiler/frontend/ampere/lower_to_maxwell.h9
1 files changed, 5 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 e1c3095abe..fb3ec893d0 100644
--- a/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h
+++ b/src/shader_recompiler/frontend/ampere/lower_to_maxwell.h
@@ -1658,12 +1658,12 @@ inline LoweredProgram LowerToMaxwell(std::span<const Instruction> code) {
case 0xb60: case 0xf60: case 0x361: { // TEX; 0xf60: handle in a uniform register; 0x361: TEX.B
// Bindless forms become Maxwell TEX.B, the handle first among the meta registers (the
// texture pass tracks it back to its constant buffer words). 0x361 lists the handle
- // right after the coordinates (see general_tex); forms with a LOD value or offsets,
+ // right after the coordinates, then the LOD (see general_tex); forms with offsets,
// whose place next to the handle is unverified, are not taken.
const bool bindless = opcode != 0xb60;
const u32 handle = opcode == 0xf60 ? uniform_register(insn.Bits(40, 6)) : 255;
if (bindless && ((opcode == 0xf60 && (handle == ~0U || handle >= 246 || insn.Bits(46, 13))) ||
- (opcode == 0x361 && (insn.Bits(40, 19) || insn.Bits(87, 3) > 1 || insn.Bits(76, 1)))))
+ (opcode == 0x361 && (insn.Bits(40, 19) || insn.Bits(87, 3) > 3 || insn.Bits(76, 1)))))
return fail(index, "native bindless texture mode");
const u32 mask = insn.Bits(72, 4);
const u32 second_dest = insn.Bits(64, 8);
@@ -1708,11 +1708,12 @@ inline LoweredProgram LowerToMaxwell(std::span<const Instruction> code) {
const u32 coordinates = coordinate_count[dimension];
const bool has_lod = lod == 2 || lod == 3 || lod == 6 || lod == 7;
// 0x361's handle is one more value after the coordinates: 2D.DC is (x, y | handle,
- // reference), ARRAY_2D is (layer, x | y, handle).
+ // reference), ARRAY_2D is (layer, x | y, handle); with five or more values the
+ // coordinates keep Ra (CUBE.LL is (x, y, z | handle, LOD)).
const u32 handle_slot = opcode == 0x361 ? 1 : 0;
const u32 count = coordinates + handle_slot + (has_lod ? 1 : 0) + (offsets ? 1 : 0) +
(depth_compare ? 1 : 0);
- const u32 in_a = count <= 4 ? (count + 1) / 2 : 4;
+ const u32 in_a = count <= 4 ? (count + 1) / 2 : opcode == 0x361 ? coordinates : 4;
const auto value = [&](u32 i) -> u32 {
if (i < in_a) return source_a == 255 ? 255U : source_a + i;
return source_b == 255 ? 255U : source_b + (i - in_a);