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 7025f14a2..421880b50 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,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "common/bit_field.h" @@ -39,14 +40,55 @@ void TranslatorVisitor::ISBERD(u64 insn) { if (isberd.o != 0) { throw NotImplementedException("O"); } - if (isberd.mode != Mode::Default) { + + // Get the source register value as the buffer index + const IR::U32 buffer_index{X(isberd.src_reg)}; + + // Read from the internal stage buffer based on mode + IR::F32 result_f32; + switch (isberd.mode) { + case Mode::Default: + // Default mode: read from stage buffer using the index + result_f32 = ir.GetAttributeIndexed(buffer_index); + break; + case Mode::Patch: + // Patch mode: read patch data + result_f32 = ir.GetPatch(static_cast(buffer_index.U32())); + break; + case Mode::Prim: + // Prim mode: read primitive data + result_f32 = ir.GetAttributeIndexed(buffer_index); + break; + case Mode::Attr: + // Attr mode: read attribute data + result_f32 = ir.GetAttributeIndexed(buffer_index); + break; + default: throw NotImplementedException("Mode {}", isberd.mode.Value()); } - if (isberd.shift != Shift::Default) { + + // Convert float result to unsigned integer + IR::U32 result = ir.ConvertFToU(32, result_f32); + + // Apply shift operation if specified + switch (isberd.shift) { + case Shift::Default: + // No shift needed + break; + case Shift::U16: + // Shift right by 16 bits + result = ir.ShiftRightLogical(result, ir.Imm32(16)); + break; + case Shift::B32: + // Shift right by 32 bits + result = ir.ShiftRightLogical(result, ir.Imm32(32)); + break; + default: throw NotImplementedException("Shift {}", isberd.shift.Value()); } - LOG_WARNING(Shader, "(STUBBED) called"); - X(isberd.dest_reg, X(isberd.src_reg)); + + // Store result in destination register + X(isberd.dest_reg, result); } } // namespace Shader::Maxwell