summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode.cpp
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-06-24 21:01:49 -0400
committerGravatar FernandoS272019-07-09 08:14:36 -0400
commitc218ae4b022a9b47366e88441220fa6c66bcae4b (patch)
tree15f7037f9da6a2bd7757b9f796276026fd01f6c5 /src/video_core/shader/decode.cpp
parentshader_ir: Implement a new shader scanner (diff)
downloadyuzu-c218ae4b022a9b47366e88441220fa6c66bcae4b.tar.gz
yuzu-c218ae4b022a9b47366e88441220fa6c66bcae4b.tar.xz
yuzu-c218ae4b022a9b47366e88441220fa6c66bcae4b.zip
shader_ir: Remove the old scanner.
Diffstat (limited to 'src/video_core/shader/decode.cpp')
-rw-r--r--src/video_core/shader/decode.cpp66
1 files changed, 0 insertions, 66 deletions
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp
index 7f433c56b..65029d35e 100644
--- a/src/video_core/shader/decode.cpp
+++ b/src/video_core/shader/decode.cpp
@@ -22,20 +22,6 @@ using Tegra::Shader::OpCode;
22 22
23namespace { 23namespace {
24 24
25/// Merges exit method of two parallel branches.
26constexpr ExitMethod ParallelExit(ExitMethod a, ExitMethod b) {
27 if (a == ExitMethod::Undetermined) {
28 return b;
29 }
30 if (b == ExitMethod::Undetermined) {
31 return a;
32 }
33 if (a == b) {
34 return a;
35 }
36 return ExitMethod::Conditional;
37}
38
39/** 25/**
40 * Returns whether the instruction at the specified offset is a 'sched' instruction. 26 * Returns whether the instruction at the specified offset is a 'sched' instruction.
41 * Sched instructions always appear before a sequence of 3 instructions. 27 * Sched instructions always appear before a sequence of 3 instructions.
@@ -79,58 +65,6 @@ void ShaderIR::Decode() {
79 return; 65 return;
80} 66}
81 67
82ExitMethod ShaderIR::Scan(u32 begin, u32 end, std::set<u32>& labels) {
83 const auto [iter, inserted] =
84 exit_method_map.emplace(std::make_pair(begin, end), ExitMethod::Undetermined);
85 ExitMethod& exit_method = iter->second;
86 if (!inserted)
87 return exit_method;
88
89 for (u32 offset = begin; offset != end && offset != MAX_PROGRAM_LENGTH; ++offset) {
90 coverage_begin = std::min(coverage_begin, offset);
91 coverage_end = std::max(coverage_end, offset + 1);
92
93 const Instruction instr = {program_code[offset]};
94 const auto opcode = OpCode::Decode(instr);
95 if (!opcode)
96 continue;
97 switch (opcode->get().GetId()) {
98 case OpCode::Id::EXIT: {
99 // The EXIT instruction can be predicated, which means that the shader can conditionally
100 // end on this instruction. We have to consider the case where the condition is not met
101 // and check the exit method of that other basic block.
102 using Tegra::Shader::Pred;
103 if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) {
104 return exit_method = ExitMethod::AlwaysEnd;
105 } else {
106 const ExitMethod not_met = Scan(offset + 1, end, labels);
107 return exit_method = ParallelExit(ExitMethod::AlwaysEnd, not_met);
108 }
109 }
110 case OpCode::Id::BRA: {
111 const u32 target = offset + instr.bra.GetBranchTarget();
112 labels.insert(target);
113 const ExitMethod no_jmp = Scan(offset + 1, end, labels);
114 const ExitMethod jmp = Scan(target, end, labels);
115 return exit_method = ParallelExit(no_jmp, jmp);
116 }
117 case OpCode::Id::SSY:
118 case OpCode::Id::PBK: {
119 // The SSY and PBK use a similar encoding as the BRA instruction.
120 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
121 "Constant buffer branching is not supported");
122 const u32 target = offset + instr.bra.GetBranchTarget();
123 labels.insert(target);
124 // Continue scanning for an exit method.
125 break;
126 }
127 default:
128 break;
129 }
130 }
131 return exit_method = ExitMethod::AlwaysReturn;
132}
133
134NodeBlock ShaderIR::DecodeRange(u32 begin, u32 end) { 68NodeBlock ShaderIR::DecodeRange(u32 begin, u32 end) {
135 NodeBlock basic_block; 69 NodeBlock basic_block;
136 for (u32 pc = begin; pc < (begin > end ? MAX_PROGRAM_LENGTH : end);) { 70 for (u32 pc = begin; pc < (begin > end ? MAX_PROGRAM_LENGTH : end);) {