diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2021-06-21 06:07:10 +0200 |
---|---|---|
committer | ameerj <52414509+ameerj@users.noreply.github.com> | 2021-07-23 03:51:39 +0200 |
commit | 808ef97a086e7cc58a3ceded1de516ad6a6be5d3 (patch) | |
tree | b79be02801ddadb44940d2c77fa0ae5c571dc557 /src/shader_recompiler/backend/spirv/emit_spirv.cpp | |
parent | gl_graphics_pipeline: Fix assembly shaders check for transform feedbacks (diff) | |
download | yuzu-808ef97a086e7cc58a3ceded1de516ad6a6be5d3.tar yuzu-808ef97a086e7cc58a3ceded1de516ad6a6be5d3.tar.gz yuzu-808ef97a086e7cc58a3ceded1de516ad6a6be5d3.tar.bz2 yuzu-808ef97a086e7cc58a3ceded1de516ad6a6be5d3.tar.lz yuzu-808ef97a086e7cc58a3ceded1de516ad6a6be5d3.tar.xz yuzu-808ef97a086e7cc58a3ceded1de516ad6a6be5d3.tar.zst yuzu-808ef97a086e7cc58a3ceded1de516ad6a6be5d3.zip |
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_spirv.cpp')
-rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv.cpp | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index fd59b4d0a..278c262f8 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -8,6 +8,7 @@ #include <utility> #include <vector> +#include "common/settings.h" #include "shader_recompiler/backend/spirv/emit_spirv.h" #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" #include "shader_recompiler/frontend/ir/basic_block.h" @@ -151,9 +152,25 @@ void Traverse(EmitContext& ctx, IR::Program& program) { } break; case IR::AbstractSyntaxNode::Type::Repeat: { + Id cond{ctx.Def(node.data.repeat.cond)}; + if (!Settings::values.disable_shader_loop_safety_checks) { + const Id pointer_type{ctx.TypePointer(spv::StorageClass::Private, ctx.U32[1])}; + const Id safety_counter{ctx.AddGlobalVariable( + pointer_type, spv::StorageClass::Private, ctx.Const(0x2000u))}; + if (ctx.profile.supported_spirv >= 0x00010400) { + ctx.interfaces.push_back(safety_counter); + } + const Id old_counter{ctx.OpLoad(ctx.U32[1], safety_counter)}; + const Id new_counter{ctx.OpISub(ctx.U32[1], old_counter, ctx.Const(1u))}; + ctx.OpStore(safety_counter, new_counter); + + const Id safety_cond{ + ctx.OpSGreaterThanEqual(ctx.U1, new_counter, ctx.u32_zero_value)}; + cond = ctx.OpLogicalAnd(ctx.U1, cond, safety_cond); + } const Id loop_header_label{node.data.repeat.loop_header->Definition<Id>()}; const Id merge_label{node.data.repeat.merge->Definition<Id>()}; - ctx.OpBranchConditional(ctx.Def(node.data.repeat.cond), loop_header_label, merge_label); + ctx.OpBranchConditional(cond, loop_header_label, merge_label); break; } case IR::AbstractSyntaxNode::Type::Return: |