diff options
Diffstat (limited to 'src/shader_recompiler/backend/glasm')
4 files changed, 18 insertions, 10 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_context.h b/src/shader_recompiler/backend/glasm/emit_context.h index cd4213cb7..9f86e55d3 100644 --- a/src/shader_recompiler/backend/glasm/emit_context.h +++ b/src/shader_recompiler/backend/glasm/emit_context.h | |||
| @@ -71,6 +71,7 @@ public: | |||
| 71 | std::string_view stage_name = "invalid"; | 71 | std::string_view stage_name = "invalid"; |
| 72 | std::string_view attrib_name = "invalid"; | 72 | std::string_view attrib_name = "invalid"; |
| 73 | 73 | ||
| 74 | u32 num_safety_loop_vars{}; | ||
| 74 | bool uses_y_direction{}; | 75 | bool uses_y_direction{}; |
| 75 | }; | 76 | }; |
| 76 | 77 | ||
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp index f39b02f77..79314f130 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp | |||
| @@ -6,6 +6,8 @@ | |||
| 6 | #include <string> | 6 | #include <string> |
| 7 | #include <tuple> | 7 | #include <tuple> |
| 8 | 8 | ||
| 9 | #include "common/div_ceil.h" | ||
| 10 | #include "common/settings.h" | ||
| 9 | #include "shader_recompiler/backend/bindings.h" | 11 | #include "shader_recompiler/backend/bindings.h" |
| 10 | #include "shader_recompiler/backend/glasm/emit_context.h" | 12 | #include "shader_recompiler/backend/glasm/emit_context.h" |
| 11 | #include "shader_recompiler/backend/glasm/emit_glasm.h" | 13 | #include "shader_recompiler/backend/glasm/emit_glasm.h" |
| @@ -222,6 +224,14 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) { | |||
| 222 | ctx.Add("REP;"); | 224 | ctx.Add("REP;"); |
| 223 | break; | 225 | break; |
| 224 | case IR::AbstractSyntaxNode::Type::Repeat: | 226 | case IR::AbstractSyntaxNode::Type::Repeat: |
| 227 | if (!Settings::values.disable_shader_loop_safety_checks) { | ||
| 228 | const u32 loop_index{ctx.num_safety_loop_vars++}; | ||
| 229 | const u32 vector_index{loop_index / 4}; | ||
| 230 | const char component{"xyzw"[loop_index % 4]}; | ||
| 231 | ctx.Add("SUB.S.CC loop{}.{},loop{}.{},1;" | ||
| 232 | "BRK(LT.{});", | ||
| 233 | vector_index, component, vector_index, component, component); | ||
| 234 | } | ||
| 225 | if (node.data.repeat.cond.IsImmediate()) { | 235 | if (node.data.repeat.cond.IsImmediate()) { |
| 226 | if (node.data.repeat.cond.U1()) { | 236 | if (node.data.repeat.cond.U1()) { |
| 227 | ctx.Add("ENDREP;"); | 237 | ctx.Add("ENDREP;"); |
| @@ -425,6 +435,10 @@ std::string EmitGLASM(const Profile& profile, const RuntimeInfo& runtime_info, I | |||
| 425 | if (program.info.uses_fswzadd) { | 435 | if (program.info.uses_fswzadd) { |
| 426 | header += "FSWZA[4],FSWZB[4],"; | 436 | header += "FSWZA[4],FSWZB[4],"; |
| 427 | } | 437 | } |
| 438 | const u32 num_safety_loop_vectors{Common::DivCeil(ctx.num_safety_loop_vars, 4u)}; | ||
| 439 | for (u32 index = 0; index < num_safety_loop_vectors; ++index) { | ||
| 440 | header += fmt::format("loop{},", index); | ||
| 441 | } | ||
| 428 | header += "RC;" | 442 | header += "RC;" |
| 429 | "LONG TEMP "; | 443 | "LONG TEMP "; |
| 430 | for (size_t index = 0; index < ctx.reg_alloc.NumUsedLongRegisters(); ++index) { | 444 | for (size_t index = 0; index < ctx.reg_alloc.NumUsedLongRegisters(); ++index) { |
| @@ -441,6 +455,9 @@ std::string EmitGLASM(const Profile& profile, const RuntimeInfo& runtime_info, I | |||
| 441 | "MOV.F FSWZB[2],1;" | 455 | "MOV.F FSWZB[2],1;" |
| 442 | "MOV.F FSWZB[3],-1;"; | 456 | "MOV.F FSWZB[3],-1;"; |
| 443 | } | 457 | } |
| 458 | for (u32 index = 0; index < num_safety_loop_vectors; ++index) { | ||
| 459 | header += fmt::format("MOV.S loop{},{{0x2000,0x2000,0x2000,0x2000}};", index); | ||
| 460 | } | ||
| 444 | if (ctx.uses_y_direction) { | 461 | if (ctx.uses_y_direction) { |
| 445 | header += "PARAM y_direction[1]={state.material.front.ambient};"; | 462 | header += "PARAM y_direction[1]={state.material.front.ambient};"; |
| 446 | } | 463 | } |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h index fef9ff9be..c9f4826ce 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h +++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h | |||
| @@ -42,8 +42,6 @@ void EmitSetGotoVariable(EmitContext& ctx); | |||
| 42 | void EmitGetGotoVariable(EmitContext& ctx); | 42 | void EmitGetGotoVariable(EmitContext& ctx); |
| 43 | void EmitSetIndirectBranchVariable(EmitContext& ctx); | 43 | void EmitSetIndirectBranchVariable(EmitContext& ctx); |
| 44 | void EmitGetIndirectBranchVariable(EmitContext& ctx); | 44 | void EmitGetIndirectBranchVariable(EmitContext& ctx); |
| 45 | void EmitSetLoopSafetyVariable(EmitContext& ctx); | ||
| 46 | void EmitGetLoopSafetyVariable(EmitContext& ctx); | ||
| 47 | void EmitGetCbufU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset); | 45 | void EmitGetCbufU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset); |
| 48 | void EmitGetCbufS8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset); | 46 | void EmitGetCbufS8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset); |
| 49 | void EmitGetCbufU16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset); | 47 | void EmitGetCbufU16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset); |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp index a487a0744..ff64c6924 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp | |||
| @@ -153,14 +153,6 @@ void EmitGetIndirectBranchVariable(EmitContext& ctx) { | |||
| 153 | NotImplemented(); | 153 | NotImplemented(); |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | void EmitSetLoopSafetyVariable(EmitContext& ctx) { | ||
| 157 | NotImplemented(); | ||
| 158 | } | ||
| 159 | |||
| 160 | void EmitGetLoopSafetyVariable(EmitContext& ctx) { | ||
| 161 | NotImplemented(); | ||
| 162 | } | ||
| 163 | |||
| 164 | void EmitGetZFlag(EmitContext& ctx) { | 156 | void EmitGetZFlag(EmitContext& ctx) { |
| 165 | NotImplemented(); | 157 | NotImplemented(); |
| 166 | } | 158 | } |