[shader_recompiler] ISBERD minor cleanups #211
5 changed files with 113 additions and 70 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<IR::U32>(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<u64>(isberd.mode.Value())) {
|
||||
case static_cast<u64>(Mode::Patch):
|
||||
result = ir.GetPatch(index.Patch());
|
||||
break;
|
||||
case static_cast<u64>(Mode::Prim):
|
||||
result = ir.GetAttribute(index.Attribute());
|
||||
break;
|
||||
case static_cast<u64>(Mode::Attr):
|
||||
result = ir.GetAttributeIndexed(index);
|
||||
break;
|
||||
}
|
||||
X(isberd.dest_reg, ir.BitCast<IR::U32>(result));
|
||||
auto result_u32 = ir.BitCast<IR::U32>(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<u64>(isberd.shift.Value())) {
|
||||
case static_cast<u64>(Shift::U16):
|
||||
result = ir.ShiftLeftLogical(result, static_cast<IR::U32>(ir.Imm16(1)));
|
||||
break;
|
||||
case static_cast<u64>(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<u32>(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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue