summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/citra_qt/debugger/graphics_vertex_shader.cpp12
-rw-r--r--src/video_core/shader/shader_interpreter.cpp7
-rw-r--r--src/video_core/shader/shader_jit_x64.cpp55
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] };