mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-25 09:10:15 +00:00
video_core: Correct shader interpeter address register handling. (#6910)
This commit is contained in:
parent
61cf550d0c
commit
df57012c50
@ -112,8 +112,9 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
|
|||||||
const auto& swizzle_data = setup.swizzle_data;
|
const auto& swizzle_data = setup.swizzle_data;
|
||||||
const auto& program_code = setup.program_code;
|
const auto& program_code = setup.program_code;
|
||||||
|
|
||||||
// Placeholder for invalid inputs
|
// Constants for handling invalid inputs
|
||||||
static f24 dummy_vec4_float24[4];
|
static f24 dummy_vec4_float24_zeros[4] = {f24::Zero(), f24::Zero(), f24::Zero(), f24::Zero()};
|
||||||
|
static f24 dummy_vec4_float24_ones[4] = {f24::One(), f24::One(), f24::One(), f24::One()};
|
||||||
|
|
||||||
u32 iteration = 0;
|
u32 iteration = 0;
|
||||||
bool should_stop = false;
|
bool should_stop = false;
|
||||||
@ -130,19 +131,33 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
|
|||||||
|
|
||||||
debug_data.max_offset = std::max<u32>(debug_data.max_offset, 1 + program_counter);
|
debug_data.max_offset = std::max<u32>(debug_data.max_offset, 1 + program_counter);
|
||||||
|
|
||||||
auto LookupSourceRegister = [&](const SourceRegister& source_reg) -> const f24* {
|
auto LookupSourceRegister = [&](const SourceRegister& source_reg,
|
||||||
|
int address_register_index) -> const f24* {
|
||||||
|
int index = source_reg.GetIndex();
|
||||||
switch (source_reg.GetRegisterType()) {
|
switch (source_reg.GetRegisterType()) {
|
||||||
case RegisterType::Input:
|
case RegisterType::Input:
|
||||||
return &state.registers.input[source_reg.GetIndex()].x;
|
return &state.registers.input[index].x;
|
||||||
|
|
||||||
case RegisterType::Temporary:
|
case RegisterType::Temporary:
|
||||||
return &state.registers.temporary[source_reg.GetIndex()].x;
|
return &state.registers.temporary[index].x;
|
||||||
|
|
||||||
case RegisterType::FloatUniform:
|
case RegisterType::FloatUniform:
|
||||||
return &uniforms.f[source_reg.GetIndex()].x;
|
if (address_register_index != 0) {
|
||||||
|
int offset = state.address_registers[address_register_index - 1];
|
||||||
|
if (offset < std::numeric_limits<s8>::min() ||
|
||||||
|
offset > std::numeric_limits<s8>::max()) [[unlikely]] {
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
index = (index + offset) & 0x7F;
|
||||||
|
// If the index is above 96, the result is all one.
|
||||||
|
if (index >= 96) [[unlikely]] {
|
||||||
|
return dummy_vec4_float24_ones;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &uniforms.f[index].x;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return dummy_vec4_float24;
|
return dummy_vec4_float24_zeros;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -151,18 +166,15 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
|
|||||||
const bool is_inverted =
|
const bool is_inverted =
|
||||||
(0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed));
|
(0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed));
|
||||||
|
|
||||||
const int address_offset =
|
const f24* src1_ =
|
||||||
(instr.common.address_register_index == 0)
|
LookupSourceRegister(instr.common.GetSrc1(is_inverted),
|
||||||
? 0
|
!is_inverted * instr.common.address_register_index);
|
||||||
: state.address_registers[instr.common.address_register_index - 1];
|
const f24* src2_ =
|
||||||
|
LookupSourceRegister(instr.common.GetSrc2(is_inverted),
|
||||||
|
is_inverted * instr.common.address_register_index);
|
||||||
|
|
||||||
const f24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted) +
|
const bool negate_src1 = swizzle.negate_src1.Value() != 0;
|
||||||
(is_inverted ? 0 : address_offset));
|
const bool negate_src2 = swizzle.negate_src2.Value() != 0;
|
||||||
const f24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted) +
|
|
||||||
(is_inverted ? address_offset : 0));
|
|
||||||
|
|
||||||
const bool negate_src1 = ((bool)swizzle.negate_src1 != false);
|
|
||||||
const bool negate_src2 = ((bool)swizzle.negate_src2 != false);
|
|
||||||
|
|
||||||
f24 src1[4] = {
|
f24 src1[4] = {
|
||||||
src1_[(int)swizzle.src1_selector_0.Value()],
|
src1_[(int)swizzle.src1_selector_0.Value()],
|
||||||
@ -193,7 +205,7 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
|
|||||||
? &state.registers.output[instr.common.dest.Value().GetIndex()][0]
|
? &state.registers.output[instr.common.dest.Value().GetIndex()][0]
|
||||||
: (instr.common.dest.Value() < 0x20)
|
: (instr.common.dest.Value() < 0x20)
|
||||||
? &state.registers.temporary[instr.common.dest.Value().GetIndex()][0]
|
? &state.registers.temporary[instr.common.dest.Value().GetIndex()][0]
|
||||||
: dummy_vec4_float24;
|
: dummy_vec4_float24_zeros;
|
||||||
|
|
||||||
debug_data.max_opdesc_id =
|
debug_data.max_opdesc_id =
|
||||||
std::max<u32>(debug_data.max_opdesc_id, 1 + instr.common.operand_desc_id);
|
std::max<u32>(debug_data.max_opdesc_id, 1 + instr.common.operand_desc_id);
|
||||||
@ -476,20 +488,16 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
|
|||||||
|
|
||||||
bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI);
|
bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI);
|
||||||
|
|
||||||
const int address_offset =
|
const f24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted), 0);
|
||||||
(instr.mad.address_register_index == 0)
|
const f24* src2_ =
|
||||||
? 0
|
LookupSourceRegister(instr.mad.GetSrc2(is_inverted),
|
||||||
: state.address_registers[instr.mad.address_register_index - 1];
|
!is_inverted * instr.mad.address_register_index);
|
||||||
|
const f24* src3_ = LookupSourceRegister(
|
||||||
|
instr.mad.GetSrc3(is_inverted), is_inverted * instr.mad.address_register_index);
|
||||||
|
|
||||||
const f24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted));
|
const bool negate_src1 = mad_swizzle.negate_src1.Value() != 0;
|
||||||
const f24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted) +
|
const bool negate_src2 = mad_swizzle.negate_src2.Value() != 0;
|
||||||
(!is_inverted * address_offset));
|
const bool negate_src3 = mad_swizzle.negate_src3.Value() != 0;
|
||||||
const f24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) +
|
|
||||||
(is_inverted * address_offset));
|
|
||||||
|
|
||||||
const bool negate_src1 = ((bool)mad_swizzle.negate_src1 != false);
|
|
||||||
const bool negate_src2 = ((bool)mad_swizzle.negate_src2 != false);
|
|
||||||
const bool negate_src3 = ((bool)mad_swizzle.negate_src3 != false);
|
|
||||||
|
|
||||||
f24 src1[4] = {
|
f24 src1[4] = {
|
||||||
src1_[(int)mad_swizzle.src1_selector_0.Value()],
|
src1_[(int)mad_swizzle.src1_selector_0.Value()],
|
||||||
@ -532,7 +540,7 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
|
|||||||
? &state.registers.output[instr.mad.dest.Value().GetIndex()][0]
|
? &state.registers.output[instr.mad.dest.Value().GetIndex()][0]
|
||||||
: (instr.mad.dest.Value() < 0x20)
|
: (instr.mad.dest.Value() < 0x20)
|
||||||
? &state.registers.temporary[instr.mad.dest.Value().GetIndex()][0]
|
? &state.registers.temporary[instr.mad.dest.Value().GetIndex()][0]
|
||||||
: dummy_vec4_float24;
|
: dummy_vec4_float24_zeros;
|
||||||
|
|
||||||
Record<DebugDataRecord::SRC1>(debug_data, iteration, src1);
|
Record<DebugDataRecord::SRC1>(debug_data, iteration, src1);
|
||||||
Record<DebugDataRecord::SRC2>(debug_data, iteration, src2);
|
Record<DebugDataRecord::SRC2>(debug_data, iteration, src2);
|
||||||
|
Loading…
Reference in New Issue
Block a user