From b50bed8c92c14989dfb20f7292dced4342cfc82b Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Wed, 9 Mar 2016 14:48:45 +0100 Subject: [PATCH] Fix MAD encoding (MADI might be broken) --- .../debugger/graphics_vertex_shader.cpp | 12 +++- src/video_core/shader/shader_interpreter.cpp | 7 ++- src/video_core/shader/shader_jit_x64.cpp | 55 ++++++++++--------- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/citra_qt/debugger/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics_vertex_shader.cpp index a11c61667..64cf7f0ef 100644 --- a/src/citra_qt/debugger/graphics_vertex_shader.cpp +++ b/src/citra_qt/debugger/graphics_vertex_shader.cpp @@ -179,9 +179,17 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con AlignToColumn(kOutputColumnWidth); print_input(output, src1, swizzle.negate_src1, SelectorToString(swizzle.src1_selector)); AlignToColumn(kInputOperandColumnWidth); - print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector)); + if (src_is_inverted) { + print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector)); + } else { + print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector), true, instr.mad.AddressRegisterName()); + } AlignToColumn(kInputOperandColumnWidth); - print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector)); + if (src_is_inverted) { + print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector), true, instr.mad.AddressRegisterName()); + } else { + print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector)); + } AlignToColumn(kInputOperandColumnWidth); break; } diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp index 79fcc56b9..295a2466b 100644 --- a/src/video_core/shader/shader_interpreter.cpp +++ b/src/video_core/shader/shader_interpreter.cpp @@ -413,9 +413,12 @@ void RunInterpreter(UnitState& state) { bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI); + const int address_offset = (instr.mad.address_register_index == 0) + ? 0 : state.address_registers[instr.mad.address_register_index - 1]; + const float24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted)); - const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted)); - const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted)); + const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted) + (!is_inverted * address_offset)); + const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) + ( is_inverted * address_offset)); const bool negate_src1 = ((bool)swizzle.negate_src1 != false); const bool negate_src2 = ((bool)swizzle.negate_src2 != false); diff --git a/src/video_core/shader/shader_jit_x64.cpp b/src/video_core/shader/shader_jit_x64.cpp index 5083d7e54..443bcbbef 100644 --- a/src/video_core/shader/shader_jit_x64.cpp +++ b/src/video_core/shader/shader_jit_x64.cpp @@ -160,40 +160,41 @@ void JitCompiler::Compile_SwizzleSrc(Instruction instr, unsigned src_num, Source ASSERT_MSG(src_offset == src_offset_disp, "Source register offset too large for int type"); unsigned operand_desc_id; + + const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); + + unsigned address_register_index; + unsigned offset_src; + if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD || instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI) { - // The MAD and MADI instructions do not use the address offset registers, so loading the - // source is a bit simpler here - operand_desc_id = instr.mad.operand_desc_id; - - // Load the source - MOVAPS(dest, MDisp(src_ptr, src_offset_disp)); + offset_src = is_inverted ? 3 : 2; + address_register_index = instr.mad.address_register_index; } else { operand_desc_id = instr.common.operand_desc_id; + offset_src = is_inverted ? 2 : 1; + address_register_index = instr.common.address_register_index; + } - const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); - unsigned offset_src = is_inverted ? 2 : 1; - - if (src_num == offset_src && instr.common.address_register_index != 0) { - switch (instr.common.address_register_index) { - case 1: // address offset 1 - MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_0, SCALE_1, src_offset_disp)); - break; - case 2: // address offset 2 - MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_1, SCALE_1, src_offset_disp)); - break; - case 3: // address offset 3 - MOVAPS(dest, MComplex(src_ptr, LOOPCOUNT_REG, SCALE_1, src_offset_disp)); - break; - default: - UNREACHABLE(); - break; - } - } else { - // Load the source - MOVAPS(dest, MDisp(src_ptr, src_offset_disp)); + if (src_num == offset_src && address_register_index != 0) { + switch (address_register_index) { + case 1: // address offset 1 + MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_0, SCALE_1, src_offset_disp)); + break; + case 2: // address offset 2 + MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_1, SCALE_1, src_offset_disp)); + break; + case 3: // address offset 3 + MOVAPS(dest, MComplex(src_ptr, LOOPCOUNT_REG, SCALE_1, src_offset_disp)); + break; + default: + UNREACHABLE(); + break; } + } else { + // Load the source + MOVAPS(dest, MDisp(src_ptr, src_offset_disp)); } SwizzlePattern swiz = { g_state.vs.swizzle_data[operand_desc_id] };