diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/internal_stage_buffer_entry_read.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/internal_stage_buffer_entry_read.cpp index 59ca4b15a3..d71c65069b 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/internal_stage_buffer_entry_read.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/internal_stage_buffer_entry_read.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -37,16 +40,56 @@ void TranslatorVisitor::ISBERD(u64 insn) { } const isberd{insn}; if (isberd.skew != 0) { - throw NotImplementedException("SKEW"); + IR::U32 current_lane_id{ir.LaneId()}; + IR::U32 result{ir.IAdd(X(isberd.src_reg), current_lane_id)}; + X(isberd.dest_reg, result); } if (isberd.o != 0) { - throw NotImplementedException("O"); + IR::U32 address{}; + IR::F32 result{}; + if (isberd.src_reg_num == 0xFF) { + address = ir.Imm32(isberd.imm); + result = ir.GetAttributeIndexed(address); + } else { + IR::U32 offset = ir.Imm32(isberd.imm); + address = ir.IAdd(X(isberd.src_reg), offset); + result = ir.GetAttributeIndexed(address); + } + X(isberd.dest_reg, ir.BitCast(result)); } if (isberd.mode != Mode::Default) { - throw NotImplementedException("Mode {}", isberd.mode.Value()); + IR::F32 result{}; + IR::U32 index{}; + if (isberd.src_reg_num == 0xFF) { + index = ir.Imm32(isberd.imm); + } else { + index = ir.IAdd(X(isberd.src_reg), ir.Imm32(isberd.imm)); + } + + switch (static_cast(isberd.mode.Value())) { + case static_cast(Mode::Patch): + result = ir.GetPatch(index.Patch()); + break; + case static_cast(Mode::Prim): + result = ir.GetAttribute(index.Attribute()); + break; + case static_cast(Mode::Attr): + result = ir.GetAttributeIndexed(index); + break; + } + X(isberd.dest_reg, ir.BitCast(result)); } if (isberd.shift != Shift::Default) { - throw NotImplementedException("Shift {}", isberd.shift.Value()); + IR::U32 result{}; + switch (static_cast(isberd.shift.Value())) { + case static_cast(Shift::U16): + result = ir.ShiftLeftLogical(result, static_cast(ir.Imm16(1))); + break; + case static_cast(Shift::B32): + result = ir.ShiftLeftLogical(result, ir.Imm32(1)); + break; + } + X(isberd.dest_reg, result); } //LOG_DEBUG(Shader, "(STUBBED) called {}", insn); if (isberd.src_reg_num == 0xFF) {