summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/maxwell
diff options
context:
space:
mode:
authorGravatar FernandoS272021-04-18 19:10:55 +0200
committerGravatar ameerj2021-07-22 21:51:29 -0400
commitda936d6ad8cef5418b7644754ee4bcbf7f6125f8 (patch)
tree63cb827cfcf4a315287d4c32842f681f378da2e4 /src/shader_recompiler/frontend/maxwell
parentvk_graphics_pipeline: Fix texture buffer descriptors (diff)
downloadyuzu-da936d6ad8cef5418b7644754ee4bcbf7f6125f8.tar.gz
yuzu-da936d6ad8cef5418b7644754ee4bcbf7f6125f8.tar.xz
yuzu-da936d6ad8cef5418b7644754ee4bcbf7f6125f8.zip
shader: Implement delegation of Exit to dispatcher on CFG
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell')
-rw-r--r--src/shader_recompiler/frontend/maxwell/control_flow.cpp41
-rw-r--r--src/shader_recompiler/frontend/maxwell/control_flow.h9
2 files changed, 47 insertions, 3 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/control_flow.cpp b/src/shader_recompiler/frontend/maxwell/control_flow.cpp
index 9811183f1..298faa03e 100644
--- a/src/shader_recompiler/frontend/maxwell/control_flow.cpp
+++ b/src/shader_recompiler/frontend/maxwell/control_flow.cpp
@@ -185,8 +185,20 @@ Function::Function(ObjectPool<Block>& block_pool, Location start_address)
185 label.block->branch_false = nullptr; 185 label.block->branch_false = nullptr;
186} 186}
187 187
188CFG::CFG(Environment& env_, ObjectPool<Block>& block_pool_, Location start_address) 188CFG::CFG(Environment& env_, ObjectPool<Block>& block_pool_, Location start_address,
189 : env{env_}, block_pool{block_pool_}, program_start{start_address} { 189 bool exits_to_dispatcher_)
190 : env{env_}, block_pool{block_pool_}, program_start{start_address}, exits_to_dispatcher{
191 exits_to_dispatcher_} {
192 if (exits_to_dispatcher) {
193 dispatch_block = block_pool.Create(Block{});
194 dispatch_block->begin = {};
195 dispatch_block->end = {};
196 dispatch_block->end_class = EndClass::Exit;
197 dispatch_block->cond = IR::Condition(true);
198 dispatch_block->stack = {};
199 dispatch_block->branch_true = nullptr;
200 dispatch_block->branch_false = nullptr;
201 }
190 functions.emplace_back(block_pool, start_address); 202 functions.emplace_back(block_pool, start_address);
191 for (FunctionId function_id = 0; function_id < functions.size(); ++function_id) { 203 for (FunctionId function_id = 0; function_id < functions.size(); ++function_id) {
192 while (!functions[function_id].labels.empty()) { 204 while (!functions[function_id].labels.empty()) {
@@ -196,6 +208,12 @@ CFG::CFG(Environment& env_, ObjectPool<Block>& block_pool_, Location start_addre
196 AnalyzeLabel(function_id, label); 208 AnalyzeLabel(function_id, label);
197 } 209 }
198 } 210 }
211 if (exits_to_dispatcher) {
212 const auto it = functions[0].blocks.rbegin();
213 dispatch_block->begin = it->end + 1;
214 dispatch_block->end = it->end + 1;
215 functions[0].blocks.insert(*dispatch_block);
216 }
199} 217}
200 218
201void CFG::AnalyzeLabel(FunctionId function_id, Label& label) { 219void CFG::AnalyzeLabel(FunctionId function_id, Label& label) {
@@ -462,11 +480,22 @@ CFG::AnalysisState CFG::AnalyzeEXIT(Block* block, FunctionId function_id, Locati
462 // EXIT will never be taken 480 // EXIT will never be taken
463 return AnalysisState::Continue; 481 return AnalysisState::Continue;
464 } 482 }
483 if (exits_to_dispatcher && function_id != 0) {
484 throw NotImplementedException("Dispatch EXIT on external function.");
485 }
465 if (pred != Predicate{true} || flow_test != IR::FlowTest::T) { 486 if (pred != Predicate{true} || flow_test != IR::FlowTest::T) {
466 if (block->stack.Peek(Token::PEXIT).has_value()) { 487 if (block->stack.Peek(Token::PEXIT).has_value()) {
467 throw NotImplementedException("Conditional EXIT with PEXIT token"); 488 throw NotImplementedException("Conditional EXIT with PEXIT token");
468 } 489 }
469 const IR::Condition cond{flow_test, static_cast<IR::Pred>(pred.index), pred.negated}; 490 const IR::Condition cond{flow_test, static_cast<IR::Pred>(pred.index), pred.negated};
491 if (exits_to_dispatcher) {
492 block->end = pc;
493 block->branch_true = dispatch_block;
494 block->end_class = EndClass::Branch;
495 block->cond = cond;
496 block->branch_false = AddLabel(block, block->stack, pc + 1, function_id);
497 return AnalysisState::Branch;
498 }
470 AnalyzeCondInst(block, function_id, pc, EndClass::Exit, cond); 499 AnalyzeCondInst(block, function_id, pc, EndClass::Exit, cond);
471 return AnalysisState::Branch; 500 return AnalysisState::Branch;
472 } 501 }
@@ -477,6 +506,14 @@ CFG::AnalysisState CFG::AnalyzeEXIT(Block* block, FunctionId function_id, Locati
477 block->branch_false = nullptr; 506 block->branch_false = nullptr;
478 return AnalysisState::Branch; 507 return AnalysisState::Branch;
479 } 508 }
509 if (exits_to_dispatcher) {
510 block->cond = IR::Condition{true};
511 block->end = pc;
512 block->end_class = EndClass::Branch;
513 block->branch_true = dispatch_block;
514 block->branch_false = nullptr;
515 return AnalysisState::Branch;
516 }
480 block->end = pc + 1; 517 block->end = pc + 1;
481 block->end_class = EndClass::Exit; 518 block->end_class = EndClass::Exit;
482 return AnalysisState::Branch; 519 return AnalysisState::Branch;
diff --git a/src/shader_recompiler/frontend/maxwell/control_flow.h b/src/shader_recompiler/frontend/maxwell/control_flow.h
index 89966b16a..0e515c3b6 100644
--- a/src/shader_recompiler/frontend/maxwell/control_flow.h
+++ b/src/shader_recompiler/frontend/maxwell/control_flow.h
@@ -111,7 +111,8 @@ class CFG {
111 }; 111 };
112 112
113public: 113public:
114 explicit CFG(Environment& env, ObjectPool<Block>& block_pool, Location start_address); 114 explicit CFG(Environment& env, ObjectPool<Block>& block_pool, Location start_address,
115 bool exits_to_dispatcher = false);
115 116
116 CFG& operator=(const CFG&) = delete; 117 CFG& operator=(const CFG&) = delete;
117 CFG(const CFG&) = delete; 118 CFG(const CFG&) = delete;
@@ -128,6 +129,10 @@ public:
128 return std::span(functions.data(), functions.size()); 129 return std::span(functions.data(), functions.size());
129 } 130 }
130 131
132 [[nodiscard]] bool ExitsToDispatcher() const {
133 return exits_to_dispatcher;
134 }
135
131private: 136private:
132 void AnalyzeLabel(FunctionId function_id, Label& label); 137 void AnalyzeLabel(FunctionId function_id, Label& label);
133 138
@@ -158,6 +163,8 @@ private:
158 boost::container::small_vector<Function, 1> functions; 163 boost::container::small_vector<Function, 1> functions;
159 FunctionId current_function_id{0}; 164 FunctionId current_function_id{0};
160 Location program_start; 165 Location program_start;
166 bool exits_to_dispatcher{};
167 Block* dispatch_block{};
161}; 168};
162 169
163} // namespace Shader::Maxwell::Flow 170} // namespace Shader::Maxwell::Flow