summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/backend/glasm
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-06-21 06:07:10 +0200
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:39 +0200
commit808ef97a086e7cc58a3ceded1de516ad6a6be5d3 (patch)
treeb79be02801ddadb44940d2c77fa0ae5c571dc557 /src/shader_recompiler/backend/glasm
parentgl_graphics_pipeline: Fix assembly shaders check for transform feedbacks (diff)
downloadyuzu-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/glasm')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_context.h1
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm.cpp17
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_instructions.h2
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp8
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:
std::string_view stage_name = "invalid";
std::string_view attrib_name = "invalid";
+ u32 num_safety_loop_vars{};
bool uses_y_direction{};
};
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 @@
#include <string>
#include <tuple>
+#include "common/div_ceil.h"
+#include "common/settings.h"
#include "shader_recompiler/backend/bindings.h"
#include "shader_recompiler/backend/glasm/emit_context.h"
#include "shader_recompiler/backend/glasm/emit_glasm.h"
@@ -222,6 +224,14 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
ctx.Add("REP;");
break;
case IR::AbstractSyntaxNode::Type::Repeat:
+ if (!Settings::values.disable_shader_loop_safety_checks) {
+ const u32 loop_index{ctx.num_safety_loop_vars++};
+ const u32 vector_index{loop_index / 4};
+ const char component{"xyzw"[loop_index % 4]};
+ ctx.Add("SUB.S.CC loop{}.{},loop{}.{},1;"
+ "BRK(LT.{});",
+ vector_index, component, vector_index, component, component);
+ }
if (node.data.repeat.cond.IsImmediate()) {
if (node.data.repeat.cond.U1()) {
ctx.Add("ENDREP;");
@@ -425,6 +435,10 @@ std::string EmitGLASM(const Profile& profile, const RuntimeInfo& runtime_info, I
if (program.info.uses_fswzadd) {
header += "FSWZA[4],FSWZB[4],";
}
+ const u32 num_safety_loop_vectors{Common::DivCeil(ctx.num_safety_loop_vars, 4u)};
+ for (u32 index = 0; index < num_safety_loop_vectors; ++index) {
+ header += fmt::format("loop{},", index);
+ }
header += "RC;"
"LONG TEMP ";
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
"MOV.F FSWZB[2],1;"
"MOV.F FSWZB[3],-1;";
}
+ for (u32 index = 0; index < num_safety_loop_vectors; ++index) {
+ header += fmt::format("MOV.S loop{},{{0x2000,0x2000,0x2000,0x2000}};", index);
+ }
if (ctx.uses_y_direction) {
header += "PARAM y_direction[1]={state.material.front.ambient};";
}
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);
void EmitGetGotoVariable(EmitContext& ctx);
void EmitSetIndirectBranchVariable(EmitContext& ctx);
void EmitGetIndirectBranchVariable(EmitContext& ctx);
-void EmitSetLoopSafetyVariable(EmitContext& ctx);
-void EmitGetLoopSafetyVariable(EmitContext& ctx);
void EmitGetCbufU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset);
void EmitGetCbufS8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset);
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) {
NotImplemented();
}
-void EmitSetLoopSafetyVariable(EmitContext& ctx) {
- NotImplemented();
-}
-
-void EmitGetLoopSafetyVariable(EmitContext& ctx) {
- NotImplemented();
-}
-
void EmitGetZFlag(EmitContext& ctx) {
NotImplemented();
}