diff options
| author | 2021-06-21 01:07:10 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:39 -0400 | |
| commit | 808ef97a086e7cc58a3ceded1de516ad6a6be5d3 (patch) | |
| tree | b79be02801ddadb44940d2c77fa0ae5c571dc557 /src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | |
| parent | gl_graphics_pipeline: Fix assembly shaders check for transform feedbacks (diff) | |
| download | yuzu-808ef97a086e7cc58a3ceded1de516ad6a6be5d3.tar.gz yuzu-808ef97a086e7cc58a3ceded1de516ad6a6be5d3.tar.xz yuzu-808ef97a086e7cc58a3ceded1de516ad6a6be5d3.zip | |
shader: Move loop safety tests to code emission
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | 37 |
1 files changed, 4 insertions, 33 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp index 0fb870a69..10d05dc4c 100644 --- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | 15 | ||
| 16 | #include <boost/intrusive/list.hpp> | 16 | #include <boost/intrusive/list.hpp> |
| 17 | 17 | ||
| 18 | #include "common/settings.h" | ||
| 19 | #include "shader_recompiler/environment.h" | 18 | #include "shader_recompiler/environment.h" |
| 20 | #include "shader_recompiler/frontend/ir/basic_block.h" | 19 | #include "shader_recompiler/frontend/ir/basic_block.h" |
| 21 | #include "shader_recompiler/frontend/ir/ir_emitter.h" | 20 | #include "shader_recompiler/frontend/ir/ir_emitter.h" |
| @@ -663,7 +662,7 @@ public: | |||
| 663 | Visit(root_stmt, nullptr, nullptr); | 662 | Visit(root_stmt, nullptr, nullptr); |
| 664 | 663 | ||
| 665 | IR::Block& first_block{*syntax_list.front().data.block}; | 664 | IR::Block& first_block{*syntax_list.front().data.block}; |
| 666 | IR::IREmitter ir = IR::IREmitter(first_block, first_block.begin()); | 665 | IR::IREmitter ir(first_block, first_block.begin()); |
| 667 | ir.Prologue(); | 666 | ir.Prologue(); |
| 668 | } | 667 | } |
| 669 | 668 | ||
| @@ -741,27 +740,8 @@ private: | |||
| 741 | } | 740 | } |
| 742 | case StatementType::Loop: { | 741 | case StatementType::Loop: { |
| 743 | IR::Block* const loop_header_block{block_pool.Create(inst_pool)}; | 742 | IR::Block* const loop_header_block{block_pool.Create(inst_pool)}; |
| 744 | const u32 this_loop_id{loop_id++}; | 743 | if (current_block) { |
| 745 | 744 | current_block->AddBranch(loop_header_block); | |
| 746 | if (Settings::values.disable_shader_loop_safety_checks) { | ||
| 747 | if (current_block) { | ||
| 748 | current_block->AddBranch(loop_header_block); | ||
| 749 | } | ||
| 750 | } else { | ||
| 751 | IR::Block* const init_block{block_pool.Create(inst_pool)}; | ||
| 752 | IR::IREmitter ir{*init_block}; | ||
| 753 | |||
| 754 | static constexpr u32 SAFETY_THRESHOLD = 0x1000; | ||
| 755 | ir.SetLoopSafetyVariable(this_loop_id, ir.Imm32(SAFETY_THRESHOLD)); | ||
| 756 | |||
| 757 | if (current_block) { | ||
| 758 | current_block->AddBranch(init_block); | ||
| 759 | } | ||
| 760 | init_block->AddBranch(loop_header_block); | ||
| 761 | |||
| 762 | auto& init_node{syntax_list.emplace_back()}; | ||
| 763 | init_node.type = IR::AbstractSyntaxNode::Type::Block; | ||
| 764 | init_node.data.block = init_block; | ||
| 765 | } | 745 | } |
| 766 | auto& header_node{syntax_list.emplace_back()}; | 746 | auto& header_node{syntax_list.emplace_back()}; |
| 767 | header_node.type = IR::AbstractSyntaxNode::Type::Block; | 747 | header_node.type = IR::AbstractSyntaxNode::Type::Block; |
| @@ -779,16 +759,7 @@ private: | |||
| 779 | 759 | ||
| 780 | // The continue block is located at the end of the loop | 760 | // The continue block is located at the end of the loop |
| 781 | IR::IREmitter ir{*continue_block}; | 761 | IR::IREmitter ir{*continue_block}; |
| 782 | IR::U1 cond{VisitExpr(ir, *stmt.cond)}; | 762 | const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))}; |
| 783 | if (!Settings::values.disable_shader_loop_safety_checks) { | ||
| 784 | const IR::U32 old_counter{ir.GetLoopSafetyVariable(this_loop_id)}; | ||
| 785 | const IR::U32 new_counter{ir.ISub(old_counter, ir.Imm32(1))}; | ||
| 786 | ir.SetLoopSafetyVariable(this_loop_id, new_counter); | ||
| 787 | |||
| 788 | const IR::U1 safety_cond{ir.INotEqual(new_counter, ir.Imm32(0))}; | ||
| 789 | cond = ir.LogicalAnd(cond, safety_cond); | ||
| 790 | } | ||
| 791 | cond = ir.ConditionRef(cond); | ||
| 792 | 763 | ||
| 793 | IR::Block* const body_block{syntax_list.at(body_block_index).data.block}; | 764 | IR::Block* const body_block{syntax_list.at(body_block_index).data.block}; |
| 794 | loop_header_block->AddBranch(body_block); | 765 | loop_header_block->AddBranch(body_block); |