diff options
| author | 2021-07-08 17:22:31 -0400 | |
|---|---|---|
| committer | 2021-07-22 21:51:35 -0400 | |
| commit | 373f75d944473731408d7a72c967d5c4b37af5bb (patch) | |
| tree | a6af34845e9cae1429bbd004a36b324bb02f9932 /src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | |
| parent | shader: Comment why the array component is not read in TMML (diff) | |
| download | yuzu-373f75d944473731408d7a72c967d5c4b37af5bb.tar.gz yuzu-373f75d944473731408d7a72c967d5c4b37af5bb.tar.xz yuzu-373f75d944473731408d7a72c967d5c4b37af5bb.zip | |
shader: Add shader loop safety check settings
Also add a setting for enable Nsight Aftermath.
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp index c1e0646e6..b2b8c492a 100644 --- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | |||
| @@ -9,11 +9,13 @@ | |||
| 9 | #include <unordered_map> | 9 | #include <unordered_map> |
| 10 | #include <utility> | 10 | #include <utility> |
| 11 | #include <vector> | 11 | #include <vector> |
| 12 | #include <version> | ||
| 12 | 13 | ||
| 13 | #include <fmt/format.h> | 14 | #include <fmt/format.h> |
| 14 | 15 | ||
| 15 | #include <boost/intrusive/list.hpp> | 16 | #include <boost/intrusive/list.hpp> |
| 16 | 17 | ||
| 18 | #include "common/settings.h" | ||
| 17 | #include "shader_recompiler/environment.h" | 19 | #include "shader_recompiler/environment.h" |
| 18 | #include "shader_recompiler/frontend/ir/basic_block.h" | 20 | #include "shader_recompiler/frontend/ir/basic_block.h" |
| 19 | #include "shader_recompiler/frontend/ir/ir_emitter.h" | 21 | #include "shader_recompiler/frontend/ir/ir_emitter.h" |
| @@ -739,8 +741,25 @@ private: | |||
| 739 | } | 741 | } |
| 740 | case StatementType::Loop: { | 742 | case StatementType::Loop: { |
| 741 | IR::Block* const loop_header_block{block_pool.Create(inst_pool)}; | 743 | IR::Block* const loop_header_block{block_pool.Create(inst_pool)}; |
| 742 | if (current_block) { | 744 | const u32 this_loop_id{loop_id++}; |
| 743 | current_block->AddBranch(loop_header_block); | 745 | |
| 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 | ir.SetLoopSafetyVariable(this_loop_id, ir.Imm32(0x2000)); | ||
| 754 | |||
| 755 | if (current_block) { | ||
| 756 | current_block->AddBranch(init_block); | ||
| 757 | } | ||
| 758 | init_block->AddBranch(loop_header_block); | ||
| 759 | |||
| 760 | auto& init_node{syntax_list.emplace_back()}; | ||
| 761 | init_node.type = IR::AbstractSyntaxNode::Type::Block; | ||
| 762 | init_node.data.block = init_block; | ||
| 744 | } | 763 | } |
| 745 | auto& header_node{syntax_list.emplace_back()}; | 764 | auto& header_node{syntax_list.emplace_back()}; |
| 746 | header_node.type = IR::AbstractSyntaxNode::Type::Block; | 765 | header_node.type = IR::AbstractSyntaxNode::Type::Block; |
| @@ -758,7 +777,16 @@ private: | |||
| 758 | 777 | ||
| 759 | // The continue block is located at the end of the loop | 778 | // The continue block is located at the end of the loop |
| 760 | IR::IREmitter ir{*continue_block}; | 779 | IR::IREmitter ir{*continue_block}; |
| 761 | const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))}; | 780 | IR::U1 cond{VisitExpr(ir, *stmt.cond)}; |
| 781 | if (!Settings::values.disable_shader_loop_safety_checks) { | ||
| 782 | const IR::U32 old_counter{ir.GetLoopSafetyVariable(this_loop_id)}; | ||
| 783 | const IR::U32 new_counter{ir.ISub(old_counter, ir.Imm32(1))}; | ||
| 784 | ir.SetLoopSafetyVariable(this_loop_id, new_counter); | ||
| 785 | |||
| 786 | const IR::U1 safety_cond{ir.INotEqual(new_counter, ir.Imm32(0))}; | ||
| 787 | cond = ir.LogicalAnd(cond, safety_cond); | ||
| 788 | } | ||
| 789 | cond = ir.ConditionRef(cond); | ||
| 762 | 790 | ||
| 763 | IR::Block* const body_block{syntax_list.at(body_block_index).data.block}; | 791 | IR::Block* const body_block{syntax_list.at(body_block_index).data.block}; |
| 764 | loop_header_block->AddBranch(body_block); | 792 | loop_header_block->AddBranch(body_block); |
| @@ -863,8 +891,14 @@ private: | |||
| 863 | ObjectPool<IR::Block>& block_pool; | 891 | ObjectPool<IR::Block>& block_pool; |
| 864 | Environment& env; | 892 | Environment& env; |
| 865 | IR::AbstractSyntaxList& syntax_list; | 893 | IR::AbstractSyntaxList& syntax_list; |
| 866 | // TODO: Make this constexpr when std::vector is constexpr | 894 | u32 loop_id{}; |
| 895 | |||
| 896 | // TODO: C++20 Remove this when all compilers support constexpr std::vector | ||
| 897 | #if __cpp_lib_constexpr_vector >= 201907 | ||
| 898 | static constexpr Flow::Block dummy_flow_block; | ||
| 899 | #else | ||
| 867 | const Flow::Block dummy_flow_block; | 900 | const Flow::Block dummy_flow_block; |
| 901 | #endif | ||
| 868 | }; | 902 | }; |
| 869 | } // Anonymous namespace | 903 | } // Anonymous namespace |
| 870 | 904 | ||