From 72fb15cacc3fe3c399bd21b002922625b8f286e5 Mon Sep 17 00:00:00 2001 From: SDK Chan Date: Fri, 15 Aug 2025 20:11:08 +0200 Subject: [PATCH] [shader_recompiler] ISBERD minor cleanups (#211) Clean up some ISBERD related implementations. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/211 Reviewed-by: Shinmegumi Co-authored-by: SDK Chan Co-committed-by: SDK Chan --- src/shader_recompiler/CMakeLists.txt | 4 + .../frontend/maxwell/translate/impl/impl.cpp | 39 +++++++ .../frontend/maxwell/translate/impl/impl.h | 33 ++++++ .../impl/internal_stage_buffer_entry_read.cpp | 104 ++++++------------ src/video_core/CMakeLists.txt | 3 + 5 files changed, 113 insertions(+), 70 deletions(-) diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index 4954beda8c..5d896db93d 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + # SPDX-FileCopyrightText: 2018 yuzu Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later @@ -240,6 +243,7 @@ add_library(shader_recompiler STATIC runtime_info.h shader_info.h varying_state.h + ) target_link_libraries(shader_recompiler PUBLIC common fmt::fmt sirit SPIRV-Tools-opt SPIRV-Tools SPIRV-Tools-link) diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp index b0ebc75f7d..157e5dfaaf 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.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 @@ -268,4 +271,40 @@ void TranslatorVisitor::ResetOFlag() { SetOFlag(ir.Imm1(false)); } +IR::U32 TranslatorVisitor::apply_ISBERD_shift(IR::U32 result, Isberd::Shift shift_value) { + if (shift_value != Isberd::Shift::Default) { + return ir.ShiftLeftLogical(result, ir.Imm32(1)); + } + return result; +} + +IR::U32 TranslatorVisitor::apply_ISBERD_size_read(IR::U32 address, Isberd::SZ sz) { + switch (sz) { + case Isberd::SZ::U8: + return ir.LoadGlobalU8(ir.UConvert(64, address)); + case Isberd::SZ::U16: + return ir.LoadGlobalU16(ir.UConvert(64, address)); + case Isberd::SZ::U32: + case Isberd::SZ::F32: + return ir.LoadGlobal32(ir.UConvert(64, address)); + default: + UNREACHABLE(); + } +} + +IR::U32 TranslatorVisitor::compute_ISBERD_address(IR::Reg src_reg, u32 src_reg_num, u32 imm, u64 skew_value) { + IR::U32 address{}; + if (src_reg_num == 0xFF) { + address = ir.Imm32(imm); + } else { + auto offset = ir.Imm32(imm); + address = ir.IAdd(X(src_reg), offset); + if (skew_value != 0) { + address = ir.IAdd(address, ir.LaneId()); + } + } + + return address; +}; + } // namespace Shader::Maxwell diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h index adf7cad068..1b2547a1bd 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h @@ -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 @@ -53,6 +56,30 @@ enum class FPCompareOp : u64 { T, }; +namespace Isberd { +enum class Mode : u64 { + Default, + Patch, + Prim, + Attr, +}; + +enum class Shift : u64 { + Default, + U16, + B32, +}; + +enum class SZ : u64 { + U8, + U16, + U32, + F32, +}; + +} // namespace Isberd + + class TranslatorVisitor { public: explicit TranslatorVisitor(Environment& env_, IR::Block& block) : env{env_}, ir(block) {} @@ -381,6 +408,12 @@ public: void ResetSFlag(); void ResetCFlag(); void ResetOFlag(); + +private: + // Helper functions for various translator visitors + IR::U32 apply_ISBERD_shift(IR::U32 result, Isberd::Shift shift_value); + IR::U32 apply_ISBERD_size_read(IR::U32 address, Isberd::SZ sz_value); + IR::U32 compute_ISBERD_address(IR::Reg src_reg, u32 src_reg_num, u32 imm, u64 skew_value); }; } // namespace Shader::Maxwell 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 d71c65069b..2aaf85772d 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 @@ -9,21 +9,6 @@ #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" namespace Shader::Maxwell { -namespace { -enum class Mode : u64 { - Default, - Patch, - Prim, - Attr, -}; - -enum class Shift : u64 { - Default, - U16, - B32, -}; - -} // Anonymous namespace // Valid only for GS, TI, VS and trap void TranslatorVisitor::ISBERD(u64 insn) { @@ -35,70 +20,49 @@ void TranslatorVisitor::ISBERD(u64 insn) { BitField<24, 8, u32> imm; BitField<31, 1, u64> skew; BitField<32, 1, u64> o; - BitField<33, 2, Mode> mode; - BitField<47, 2, Shift> shift; + BitField<33, 2, Isberd::Mode> mode; + BitField<36, 4, Isberd::SZ> sz; + BitField<47, 2, Isberd::Shift> shift; } const isberd{insn}; - if (isberd.skew != 0) { - IR::U32 current_lane_id{ir.LaneId()}; - IR::U32 result{ir.IAdd(X(isberd.src_reg), current_lane_id)}; - X(isberd.dest_reg, result); - } + auto address = compute_ISBERD_address(isberd.src_reg, isberd.src_reg_num, isberd.imm, isberd.skew); if (isberd.o != 0) { - 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)); + auto result = apply_ISBERD_size_read(address, isberd.sz.Value()); + X(isberd.dest_reg, apply_ISBERD_shift(result, isberd.shift.Value())); + + return; } - if (isberd.mode != Mode::Default) { - 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)); + + if (isberd.mode != Isberd::Mode::Default) { + IR::F32 result_f32{}; + switch (isberd.mode.Value()) { + case Isberd::Mode::Patch: + result_f32 = ir.GetPatch(address.Patch()); + break; + case Isberd::Mode::Prim: + result_f32 = ir.GetAttribute(address.Attribute()); + break; + case Isberd::Mode::Attr: + result_f32 = ir.GetAttributeIndexed(address); + break; + default: + UNREACHABLE(); } - 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)); + auto result_u32 = ir.BitCast(result_f32); + X(isberd.dest_reg, apply_ISBERD_shift(result_u32, isberd.shift.Value())); + return; } - if (isberd.shift != Shift::Default) { - 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; - } + + if (isberd.skew != 0) { + auto result = ir.IAdd(X(isberd.src_reg), ir.LaneId()); X(isberd.dest_reg, result); + + return; } - //LOG_DEBUG(Shader, "(STUBBED) called {}", insn); - if (isberd.src_reg_num == 0xFF) { - IR::U32 src_imm{ir.Imm32(static_cast(isberd.imm))}; - IR::U32 result{ir.IAdd(X(isberd.src_reg), src_imm)}; - X(isberd.dest_reg, result); - } else { - X(isberd.dest_reg, X(isberd.src_reg)); - } + + // Fallback if nothing else applies + X(isberd.dest_reg, X(isberd.src_reg)); } } // namespace Shader::Maxwell diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 83111c31b0..89fe7a35f9 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + # SPDX-FileCopyrightText: 2018 yuzu Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later