summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-10 01:37:30 -0300
committerGravatar ameerj2021-07-22 21:51:31 -0400
commit6237300e3605c0b12fb65e2a8818487ec2cb4580 (patch)
tree9551638b7a4807cc1449c50214cd55de29c31e98
parentglasm: Fix moving U64 immediates to registers in GLASM (diff)
downloadyuzu-6237300e3605c0b12fb65e2a8818487ec2cb4580.tar.gz
yuzu-6237300e3605c0b12fb65e2a8818487ec2cb4580.tar.xz
yuzu-6237300e3605c0b12fb65e2a8818487ec2cb4580.zip
glasm: Fix clamps so the min value has priority on NAN on GLASM
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp27
1 files changed, 15 insertions, 12 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp
index 2aee5a56c..2e1c7d55f 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp
@@ -9,11 +9,10 @@
9#include "shader_recompiler/frontend/ir/value.h" 9#include "shader_recompiler/frontend/ir/value.h"
10 10
11namespace Shader::Backend::GLASM { 11namespace Shader::Backend::GLASM {
12 12namespace {
13template <typename InputType> 13template <typename InputType>
14static void Compare(EmitContext& ctx, IR::Inst& inst, InputType lhs, InputType rhs, 14void Compare(EmitContext& ctx, IR::Inst& inst, InputType lhs, InputType rhs, std::string_view op,
15 std::string_view op, std::string_view type, bool ordered, 15 std::string_view type, bool ordered, bool inequality = false) {
16 bool inequality = false) {
17 const Register ret{ctx.reg_alloc.Define(inst)}; 16 const Register ret{ctx.reg_alloc.Define(inst)};
18 ctx.Add("{}.{} RC.x,{},{};", op, type, lhs, rhs); 17 ctx.Add("{}.{} RC.x,{},{};", op, type, lhs, rhs);
19 if (ordered && inequality) { 18 if (ordered && inequality) {
@@ -35,6 +34,16 @@ static void Compare(EmitContext& ctx, IR::Inst& inst, InputType lhs, InputType r
35 } 34 }
36} 35}
37 36
37template <typename InputType>
38void Clamp(EmitContext& ctx, Register ret, InputType value, InputType min_value,
39 InputType max_value) {
40 // Call MAX first to properly clamp nan to min_value instead
41 ctx.Add("MAX.F {}.x,{},{};"
42 "MIN.F {}.x,{},{};",
43 ret, min_value, value, ret, ret, max_value);
44}
45} // Anonymous namespace
46
38void EmitFPAbs16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, 47void EmitFPAbs16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
39 [[maybe_unused]] Register value) { 48 [[maybe_unused]] Register value) {
40 throw NotImplementedException("GLASM instruction"); 49 throw NotImplementedException("GLASM instruction");
@@ -171,18 +180,12 @@ void EmitFPClamp16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register
171 180
172void EmitFPClamp32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value, ScalarF32 min_value, 181void EmitFPClamp32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value, ScalarF32 min_value,
173 ScalarF32 max_value) { 182 ScalarF32 max_value) {
174 const Register ret{ctx.reg_alloc.Define(inst)}; 183 Clamp(ctx, ctx.reg_alloc.Define(inst), value, min_value, max_value);
175 ctx.Add("MIN.F {}.x,{},{};"
176 "MAX.F {}.x,{},{};",
177 ret, max_value, value, ret, ret, min_value);
178} 184}
179 185
180void EmitFPClamp64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value, ScalarF64 min_value, 186void EmitFPClamp64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value, ScalarF64 min_value,
181 ScalarF64 max_value) { 187 ScalarF64 max_value) {
182 const Register ret{ctx.reg_alloc.LongDefine(inst)}; 188 Clamp(ctx, ctx.reg_alloc.LongDefine(inst), value, min_value, max_value);
183 ctx.Add("MIN.F64 {}.x,{},{};"
184 "MAX.F64 {}.x,{},{};",
185 ret, max_value, value, ret, ret, min_value);
186} 189}
187 190
188void EmitFPRoundEven16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) { 191void EmitFPRoundEven16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {