diff options
| -rw-r--r-- | src/citra_qt/debugger/graphics_vertex_shader.cpp | 12 | ||||
| -rw-r--r-- | src/video_core/shader/shader_interpreter.cpp | 7 | ||||
| -rw-r--r-- | 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 4b676f1b1..d648d4640 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 | |||
| 179 | AlignToColumn(kOutputColumnWidth); | 179 | AlignToColumn(kOutputColumnWidth); |
| 180 | print_input(output, src1, swizzle.negate_src1, SelectorToString(swizzle.src1_selector)); | 180 | print_input(output, src1, swizzle.negate_src1, SelectorToString(swizzle.src1_selector)); |
| 181 | AlignToColumn(kInputOperandColumnWidth); | 181 | AlignToColumn(kInputOperandColumnWidth); |
| 182 | print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector)); | 182 | if (src_is_inverted) { |
| 183 | print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector)); | ||
| 184 | } else { | ||
| 185 | print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector), true, instr.mad.AddressRegisterName()); | ||
| 186 | } | ||
| 183 | AlignToColumn(kInputOperandColumnWidth); | 187 | AlignToColumn(kInputOperandColumnWidth); |
| 184 | print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector)); | 188 | if (src_is_inverted) { |
| 189 | print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector), true, instr.mad.AddressRegisterName()); | ||
| 190 | } else { | ||
| 191 | print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector)); | ||
| 192 | } | ||
| 185 | AlignToColumn(kInputOperandColumnWidth); | 193 | AlignToColumn(kInputOperandColumnWidth); |
| 186 | break; | 194 | break; |
| 187 | } | 195 | } |
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<Debug>& state) { | |||
| 413 | 413 | ||
| 414 | bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI); | 414 | bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI); |
| 415 | 415 | ||
| 416 | const int address_offset = (instr.mad.address_register_index == 0) | ||
| 417 | ? 0 : state.address_registers[instr.mad.address_register_index - 1]; | ||
| 418 | |||
| 416 | const float24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted)); | 419 | const float24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted)); |
| 417 | const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted)); | 420 | const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted) + (!is_inverted * address_offset)); |
| 418 | const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted)); | 421 | const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) + ( is_inverted * address_offset)); |
| 419 | 422 | ||
| 420 | const bool negate_src1 = ((bool)swizzle.negate_src1 != false); | 423 | const bool negate_src1 = ((bool)swizzle.negate_src1 != false); |
| 421 | const bool negate_src2 = ((bool)swizzle.negate_src2 != false); | 424 | 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 | |||
| 160 | ASSERT_MSG(src_offset == src_offset_disp, "Source register offset too large for int type"); | 160 | ASSERT_MSG(src_offset == src_offset_disp, "Source register offset too large for int type"); |
| 161 | 161 | ||
| 162 | unsigned operand_desc_id; | 162 | unsigned operand_desc_id; |
| 163 | |||
| 164 | const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); | ||
| 165 | |||
| 166 | unsigned address_register_index; | ||
| 167 | unsigned offset_src; | ||
| 168 | |||
| 163 | if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD || | 169 | if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD || |
| 164 | instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI) { | 170 | instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI) { |
| 165 | // The MAD and MADI instructions do not use the address offset registers, so loading the | ||
| 166 | // source is a bit simpler here | ||
| 167 | |||
| 168 | operand_desc_id = instr.mad.operand_desc_id; | 171 | operand_desc_id = instr.mad.operand_desc_id; |
| 169 | 172 | offset_src = is_inverted ? 3 : 2; | |
| 170 | // Load the source | 173 | address_register_index = instr.mad.address_register_index; |
| 171 | MOVAPS(dest, MDisp(src_ptr, src_offset_disp)); | ||
| 172 | } else { | 174 | } else { |
| 173 | operand_desc_id = instr.common.operand_desc_id; | 175 | operand_desc_id = instr.common.operand_desc_id; |
| 176 | offset_src = is_inverted ? 2 : 1; | ||
| 177 | address_register_index = instr.common.address_register_index; | ||
| 178 | } | ||
| 174 | 179 | ||
| 175 | const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); | 180 | if (src_num == offset_src && address_register_index != 0) { |
| 176 | unsigned offset_src = is_inverted ? 2 : 1; | 181 | switch (address_register_index) { |
| 177 | 182 | case 1: // address offset 1 | |
| 178 | if (src_num == offset_src && instr.common.address_register_index != 0) { | 183 | MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_0, SCALE_1, src_offset_disp)); |
| 179 | switch (instr.common.address_register_index) { | 184 | break; |
| 180 | case 1: // address offset 1 | 185 | case 2: // address offset 2 |
| 181 | MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_0, SCALE_1, src_offset_disp)); | 186 | MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_1, SCALE_1, src_offset_disp)); |
| 182 | break; | 187 | break; |
| 183 | case 2: // address offset 2 | 188 | case 3: // address offset 3 |
| 184 | MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_1, SCALE_1, src_offset_disp)); | 189 | MOVAPS(dest, MComplex(src_ptr, LOOPCOUNT_REG, SCALE_1, src_offset_disp)); |
| 185 | break; | 190 | break; |
| 186 | case 3: // address offset 3 | 191 | default: |
| 187 | MOVAPS(dest, MComplex(src_ptr, LOOPCOUNT_REG, SCALE_1, src_offset_disp)); | 192 | UNREACHABLE(); |
| 188 | break; | 193 | break; |
| 189 | default: | ||
| 190 | UNREACHABLE(); | ||
| 191 | break; | ||
| 192 | } | ||
| 193 | } else { | ||
| 194 | // Load the source | ||
| 195 | MOVAPS(dest, MDisp(src_ptr, src_offset_disp)); | ||
| 196 | } | 194 | } |
| 195 | } else { | ||
| 196 | // Load the source | ||
| 197 | MOVAPS(dest, MDisp(src_ptr, src_offset_disp)); | ||
| 197 | } | 198 | } |
| 198 | 199 | ||
| 199 | SwizzlePattern swiz = { g_state.vs.swizzle_data[operand_desc_id] }; | 200 | SwizzlePattern swiz = { g_state.vs.swizzle_data[operand_desc_id] }; |