summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2016-05-12 19:32:44 -0400
committerGravatar bunnei2016-05-12 19:32:44 -0400
commitd474d117f6ec1196967e50f8e94b95de6044c826 (patch)
tree878b9bd2fb115e68b710774a90a687caf9501edd
parentMerge pull request #1690 from JayFoxRox/tex-type-3 (diff)
parentMove program_counter and call_stack from UnitState to interpreter (diff)
downloadyuzu-d474d117f6ec1196967e50f8e94b95de6044c826.tar.gz
yuzu-d474d117f6ec1196967e50f8e94b95de6044c826.tar.xz
yuzu-d474d117f6ec1196967e50f8e94b95de6044c826.zip
Merge pull request #1783 from JayFoxRox/cleanup-shadersetup
Cleanup ShaderSetup (Part 1)
-rw-r--r--src/citra_qt/debugger/graphics_tracing.cpp2
-rw-r--r--src/video_core/command_processor.cpp2
-rw-r--r--src/video_core/pica_state.h2
-rw-r--r--src/video_core/shader/shader.cpp2
-rw-r--r--src/video_core/shader/shader.h19
-rw-r--r--src/video_core/shader/shader_interpreter.cpp68
-rw-r--r--src/video_core/vertex_loader.cpp2
7 files changed, 47 insertions, 50 deletions
diff --git a/src/citra_qt/debugger/graphics_tracing.cpp b/src/citra_qt/debugger/graphics_tracing.cpp
index 1402f8e79..9c80f7ec9 100644
--- a/src/citra_qt/debugger/graphics_tracing.cpp
+++ b/src/citra_qt/debugger/graphics_tracing.cpp
@@ -74,7 +74,7 @@ void GraphicsTracingWidget::StartRecording() {
74 std::array<u32, 4 * 16> default_attributes; 74 std::array<u32, 4 * 16> default_attributes;
75 for (unsigned i = 0; i < 16; ++i) { 75 for (unsigned i = 0; i < 16; ++i) {
76 for (unsigned comp = 0; comp < 3; ++comp) { 76 for (unsigned comp = 0; comp < 3; ++comp) {
77 default_attributes[4 * i + comp] = nihstro::to_float24(Pica::g_state.vs.default_attributes[i][comp].ToFloat32()); 77 default_attributes[4 * i + comp] = nihstro::to_float24(Pica::g_state.vs_default_attributes[i][comp].ToFloat32());
78 } 78 }
79 } 79 }
80 80
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index e7dc5ddac..ad0da796e 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -128,7 +128,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
128 128
129 // TODO: Verify that this actually modifies the register! 129 // TODO: Verify that this actually modifies the register!
130 if (setup.index < 15) { 130 if (setup.index < 15) {
131 g_state.vs.default_attributes[setup.index] = attribute; 131 g_state.vs_default_attributes[setup.index] = attribute;
132 setup.index++; 132 setup.index++;
133 } else { 133 } else {
134 // Put each attribute into an immediate input buffer. 134 // Put each attribute into an immediate input buffer.
diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h
index 1059c6ae4..495174c25 100644
--- a/src/video_core/pica_state.h
+++ b/src/video_core/pica_state.h
@@ -25,6 +25,8 @@ struct State {
25 Shader::ShaderSetup vs; 25 Shader::ShaderSetup vs;
26 Shader::ShaderSetup gs; 26 Shader::ShaderSetup gs;
27 27
28 std::array<Math::Vec4<float24>, 16> vs_default_attributes;
29
28 struct { 30 struct {
29 union LutEntry { 31 union LutEntry {
30 // Used for raw access 32 // Used for raw access
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp
index 449fc703f..e93a9d92a 100644
--- a/src/video_core/shader/shader.cpp
+++ b/src/video_core/shader/shader.cpp
@@ -67,7 +67,6 @@ OutputVertex ShaderSetup::Run(UnitState<false>& state, const InputVertex& input,
67 67
68 MICROPROFILE_SCOPE(GPU_Shader); 68 MICROPROFILE_SCOPE(GPU_Shader);
69 69
70 state.program_counter = config.main_offset;
71 state.debug.max_offset = 0; 70 state.debug.max_offset = 0;
72 state.debug.max_opdesc_id = 0; 71 state.debug.max_opdesc_id = 0;
73 72
@@ -143,7 +142,6 @@ OutputVertex ShaderSetup::Run(UnitState<false>& state, const InputVertex& input,
143DebugData<true> ShaderSetup::ProduceDebugInfo(const InputVertex& input, int num_attributes, const Regs::ShaderConfig& config, const ShaderSetup& setup) { 142DebugData<true> ShaderSetup::ProduceDebugInfo(const InputVertex& input, int num_attributes, const Regs::ShaderConfig& config, const ShaderSetup& setup) {
144 UnitState<true> state; 143 UnitState<true> state;
145 144
146 state.program_counter = config.main_offset;
147 state.debug.max_offset = 0; 145 state.debug.max_offset = 0;
148 state.debug.max_opdesc_id = 0; 146 state.debug.max_opdesc_id = 0;
149 147
diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h
index 7f417675a..983e4a967 100644
--- a/src/video_core/shader/shader.h
+++ b/src/video_core/shader/shader.h
@@ -272,29 +272,12 @@ struct UnitState {
272 } registers; 272 } registers;
273 static_assert(std::is_pod<Registers>::value, "Structure is not POD"); 273 static_assert(std::is_pod<Registers>::value, "Structure is not POD");
274 274
275 u32 program_counter;
276 bool conditional_code[2]; 275 bool conditional_code[2];
277 276
278 // Two Address registers and one loop counter 277 // Two Address registers and one loop counter
279 // TODO: How many bits do these actually have? 278 // TODO: How many bits do these actually have?
280 s32 address_registers[3]; 279 s32 address_registers[3];
281 280
282 enum {
283 INVALID_ADDRESS = 0xFFFFFFFF
284 };
285
286 struct CallStackElement {
287 u32 final_address; // Address upon which we jump to return_address
288 u32 return_address; // Where to jump when leaving scope
289 u8 repeat_counter; // How often to repeat until this call stack element is removed
290 u8 loop_increment; // Which value to add to the loop counter after an iteration
291 // TODO: Should this be a signed value? Does it even matter?
292 u32 loop_address; // The address where we'll return to after each loop iteration
293 };
294
295 // TODO: Is there a maximal size for this?
296 boost::container::static_vector<CallStackElement, 16> call_stack;
297
298 DebugData<Debug> debug; 281 DebugData<Debug> debug;
299 282
300 static size_t InputOffset(const SourceRegister& reg) { 283 static size_t InputOffset(const SourceRegister& reg) {
@@ -340,8 +323,6 @@ struct ShaderSetup {
340 std::array<Math::Vec4<u8>, 4> i; 323 std::array<Math::Vec4<u8>, 4> i;
341 } uniforms; 324 } uniforms;
342 325
343 Math::Vec4<float24> default_attributes[16];
344
345 std::array<u32, 1024> program_code; 326 std::array<u32, 1024> program_code;
346 std::array<u32, 1024> swizzle_data; 327 std::array<u32, 1024> swizzle_data;
347 328
diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp
index 7710f7fbc..3a827d11f 100644
--- a/src/video_core/shader/shader_interpreter.cpp
+++ b/src/video_core/shader/shader_interpreter.cpp
@@ -29,8 +29,24 @@ namespace Pica {
29 29
30namespace Shader { 30namespace Shader {
31 31
32constexpr u32 INVALID_ADDRESS = 0xFFFFFFFF;
33
34struct CallStackElement {
35 u32 final_address; // Address upon which we jump to return_address
36 u32 return_address; // Where to jump when leaving scope
37 u8 repeat_counter; // How often to repeat until this call stack element is removed
38 u8 loop_increment; // Which value to add to the loop counter after an iteration
39 // TODO: Should this be a signed value? Does it even matter?
40 u32 loop_address; // The address where we'll return to after each loop iteration
41};
42
32template<bool Debug> 43template<bool Debug>
33void RunInterpreter(UnitState<Debug>& state) { 44void RunInterpreter(UnitState<Debug>& state) {
45 // TODO: Is there a maximal size for this?
46 boost::container::static_vector<CallStackElement, 16> call_stack;
47
48 u32 program_counter = g_state.regs.vs.main_offset;
49
34 const auto& uniforms = g_state.vs.uniforms; 50 const auto& uniforms = g_state.vs.uniforms;
35 const auto& swizzle_data = g_state.vs.swizzle_data; 51 const auto& swizzle_data = g_state.vs.swizzle_data;
36 const auto& program_code = g_state.vs.program_code; 52 const auto& program_code = g_state.vs.program_code;
@@ -41,16 +57,16 @@ void RunInterpreter(UnitState<Debug>& state) {
41 unsigned iteration = 0; 57 unsigned iteration = 0;
42 bool exit_loop = false; 58 bool exit_loop = false;
43 while (!exit_loop) { 59 while (!exit_loop) {
44 if (!state.call_stack.empty()) { 60 if (!call_stack.empty()) {
45 auto& top = state.call_stack.back(); 61 auto& top = call_stack.back();
46 if (state.program_counter == top.final_address) { 62 if (program_counter == top.final_address) {
47 state.address_registers[2] += top.loop_increment; 63 state.address_registers[2] += top.loop_increment;
48 64
49 if (top.repeat_counter-- == 0) { 65 if (top.repeat_counter-- == 0) {
50 state.program_counter = top.return_address; 66 program_counter = top.return_address;
51 state.call_stack.pop_back(); 67 call_stack.pop_back();
52 } else { 68 } else {
53 state.program_counter = top.loop_address; 69 program_counter = top.loop_address;
54 } 70 }
55 71
56 // TODO: Is "trying again" accurate to hardware? 72 // TODO: Is "trying again" accurate to hardware?
@@ -58,20 +74,20 @@ void RunInterpreter(UnitState<Debug>& state) {
58 } 74 }
59 } 75 }
60 76
61 const Instruction instr = { program_code[state.program_counter] }; 77 const Instruction instr = { program_code[program_counter] };
62 const SwizzlePattern swizzle = { swizzle_data[instr.common.operand_desc_id] }; 78 const SwizzlePattern swizzle = { swizzle_data[instr.common.operand_desc_id] };
63 79
64 static auto call = [](UnitState<Debug>& state, u32 offset, u32 num_instructions, 80 static auto call = [&program_counter, &call_stack](UnitState<Debug>& state, u32 offset, u32 num_instructions,
65 u32 return_offset, u8 repeat_count, u8 loop_increment) { 81 u32 return_offset, u8 repeat_count, u8 loop_increment) {
66 state.program_counter = offset - 1; // -1 to make sure when incrementing the PC we end up at the correct offset 82 program_counter = offset - 1; // -1 to make sure when incrementing the PC we end up at the correct offset
67 ASSERT(state.call_stack.size() < state.call_stack.capacity()); 83 ASSERT(call_stack.size() < call_stack.capacity());
68 state.call_stack.push_back({ offset + num_instructions, return_offset, repeat_count, loop_increment, offset }); 84 call_stack.push_back({ offset + num_instructions, return_offset, repeat_count, loop_increment, offset });
69 }; 85 };
70 Record<DebugDataRecord::CUR_INSTR>(state.debug, iteration, state.program_counter); 86 Record<DebugDataRecord::CUR_INSTR>(state.debug, iteration, program_counter);
71 if (iteration > 0) 87 if (iteration > 0)
72 Record<DebugDataRecord::NEXT_INSTR>(state.debug, iteration - 1, state.program_counter); 88 Record<DebugDataRecord::NEXT_INSTR>(state.debug, iteration - 1, program_counter);
73 89
74 state.debug.max_offset = std::max<u32>(state.debug.max_offset, 1 + state.program_counter); 90 state.debug.max_offset = std::max<u32>(state.debug.max_offset, 1 + program_counter);
75 91
76 auto LookupSourceRegister = [&](const SourceRegister& source_reg) -> const float24* { 92 auto LookupSourceRegister = [&](const SourceRegister& source_reg) -> const float24* {
77 switch (source_reg.GetRegisterType()) { 93 switch (source_reg.GetRegisterType()) {
@@ -519,7 +535,7 @@ void RunInterpreter(UnitState<Debug>& state) {
519 case OpCode::Id::JMPC: 535 case OpCode::Id::JMPC:
520 Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, state.conditional_code); 536 Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, state.conditional_code);
521 if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { 537 if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) {
522 state.program_counter = instr.flow_control.dest_offset - 1; 538 program_counter = instr.flow_control.dest_offset - 1;
523 } 539 }
524 break; 540 break;
525 541
@@ -527,7 +543,7 @@ void RunInterpreter(UnitState<Debug>& state) {
527 Record<DebugDataRecord::COND_BOOL_IN>(state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); 543 Record<DebugDataRecord::COND_BOOL_IN>(state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]);
528 544
529 if (uniforms.b[instr.flow_control.bool_uniform_id] == !(instr.flow_control.num_instructions & 1)) { 545 if (uniforms.b[instr.flow_control.bool_uniform_id] == !(instr.flow_control.num_instructions & 1)) {
530 state.program_counter = instr.flow_control.dest_offset - 1; 546 program_counter = instr.flow_control.dest_offset - 1;
531 } 547 }
532 break; 548 break;
533 549
@@ -535,7 +551,7 @@ void RunInterpreter(UnitState<Debug>& state) {
535 call(state, 551 call(state,
536 instr.flow_control.dest_offset, 552 instr.flow_control.dest_offset,
537 instr.flow_control.num_instructions, 553 instr.flow_control.num_instructions,
538 state.program_counter + 1, 0, 0); 554 program_counter + 1, 0, 0);
539 break; 555 break;
540 556
541 case OpCode::Id::CALLU: 557 case OpCode::Id::CALLU:
@@ -544,7 +560,7 @@ void RunInterpreter(UnitState<Debug>& state) {
544 call(state, 560 call(state,
545 instr.flow_control.dest_offset, 561 instr.flow_control.dest_offset,
546 instr.flow_control.num_instructions, 562 instr.flow_control.num_instructions,
547 state.program_counter + 1, 0, 0); 563 program_counter + 1, 0, 0);
548 } 564 }
549 break; 565 break;
550 566
@@ -554,7 +570,7 @@ void RunInterpreter(UnitState<Debug>& state) {
554 call(state, 570 call(state,
555 instr.flow_control.dest_offset, 571 instr.flow_control.dest_offset,
556 instr.flow_control.num_instructions, 572 instr.flow_control.num_instructions,
557 state.program_counter + 1, 0, 0); 573 program_counter + 1, 0, 0);
558 } 574 }
559 break; 575 break;
560 576
@@ -565,8 +581,8 @@ void RunInterpreter(UnitState<Debug>& state) {
565 Record<DebugDataRecord::COND_BOOL_IN>(state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); 581 Record<DebugDataRecord::COND_BOOL_IN>(state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]);
566 if (uniforms.b[instr.flow_control.bool_uniform_id]) { 582 if (uniforms.b[instr.flow_control.bool_uniform_id]) {
567 call(state, 583 call(state,
568 state.program_counter + 1, 584 program_counter + 1,
569 instr.flow_control.dest_offset - state.program_counter - 1, 585 instr.flow_control.dest_offset - program_counter - 1,
570 instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0); 586 instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0);
571 } else { 587 } else {
572 call(state, 588 call(state,
@@ -584,8 +600,8 @@ void RunInterpreter(UnitState<Debug>& state) {
584 Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, state.conditional_code); 600 Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, state.conditional_code);
585 if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { 601 if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) {
586 call(state, 602 call(state,
587 state.program_counter + 1, 603 program_counter + 1,
588 instr.flow_control.dest_offset - state.program_counter - 1, 604 instr.flow_control.dest_offset - program_counter - 1,
589 instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0); 605 instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0);
590 } else { 606 } else {
591 call(state, 607 call(state,
@@ -607,8 +623,8 @@ void RunInterpreter(UnitState<Debug>& state) {
607 623
608 Record<DebugDataRecord::LOOP_INT_IN>(state.debug, iteration, loop_param); 624 Record<DebugDataRecord::LOOP_INT_IN>(state.debug, iteration, loop_param);
609 call(state, 625 call(state,
610 state.program_counter + 1, 626 program_counter + 1,
611 instr.flow_control.dest_offset - state.program_counter + 1, 627 instr.flow_control.dest_offset - program_counter + 1,
612 instr.flow_control.dest_offset + 1, 628 instr.flow_control.dest_offset + 1,
613 loop_param.x, 629 loop_param.x,
614 loop_param.z); 630 loop_param.z);
@@ -625,7 +641,7 @@ void RunInterpreter(UnitState<Debug>& state) {
625 } 641 }
626 } 642 }
627 643
628 ++state.program_counter; 644 ++program_counter;
629 ++iteration; 645 ++iteration;
630 } 646 }
631} 647}
diff --git a/src/video_core/vertex_loader.cpp b/src/video_core/vertex_loader.cpp
index 21ae52949..83896814f 100644
--- a/src/video_core/vertex_loader.cpp
+++ b/src/video_core/vertex_loader.cpp
@@ -124,7 +124,7 @@ void VertexLoader::LoadVertex(u32 base_address, int index, int vertex, Shader::I
124 input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); 124 input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32());
125 } else if (vertex_attribute_is_default[i]) { 125 } else if (vertex_attribute_is_default[i]) {
126 // Load the default attribute if we're configured to do so 126 // Load the default attribute if we're configured to do so
127 input.attr[i] = g_state.vs.default_attributes[i]; 127 input.attr[i] = g_state.vs_default_attributes[i];
128 LOG_TRACE(HW_GPU, "Loaded default attribute %x for vertex %x (index %x): (%f, %f, %f, %f)", 128 LOG_TRACE(HW_GPU, "Loaded default attribute %x for vertex %x (index %x): (%f, %f, %f, %f)",
129 i, vertex, index, 129 i, vertex, index,
130 input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), 130 input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(),