From 6237300e3605c0b12fb65e2a8818487ec2cb4580 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 10 May 2021 01:37:30 -0300 Subject: glasm: Fix clamps so the min value has priority on NAN on GLASM --- .../backend/glasm/emit_glasm_floating_point.cpp | 27 ++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'src/shader_recompiler') 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 @@ #include "shader_recompiler/frontend/ir/value.h" namespace Shader::Backend::GLASM { - +namespace { template -static void Compare(EmitContext& ctx, IR::Inst& inst, InputType lhs, InputType rhs, - std::string_view op, std::string_view type, bool ordered, - bool inequality = false) { +void Compare(EmitContext& ctx, IR::Inst& inst, InputType lhs, InputType rhs, std::string_view op, + std::string_view type, bool ordered, bool inequality = false) { const Register ret{ctx.reg_alloc.Define(inst)}; ctx.Add("{}.{} RC.x,{},{};", op, type, lhs, rhs); if (ordered && inequality) { @@ -35,6 +34,16 @@ static void Compare(EmitContext& ctx, IR::Inst& inst, InputType lhs, InputType r } } +template +void Clamp(EmitContext& ctx, Register ret, InputType value, InputType min_value, + InputType max_value) { + // Call MAX first to properly clamp nan to min_value instead + ctx.Add("MAX.F {}.x,{},{};" + "MIN.F {}.x,{},{};", + ret, min_value, value, ret, ret, max_value); +} +} // Anonymous namespace + void EmitFPAbs16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, [[maybe_unused]] Register value) { throw NotImplementedException("GLASM instruction"); @@ -171,18 +180,12 @@ void EmitFPClamp16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register void EmitFPClamp32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value, ScalarF32 min_value, ScalarF32 max_value) { - const Register ret{ctx.reg_alloc.Define(inst)}; - ctx.Add("MIN.F {}.x,{},{};" - "MAX.F {}.x,{},{};", - ret, max_value, value, ret, ret, min_value); + Clamp(ctx, ctx.reg_alloc.Define(inst), value, min_value, max_value); } void EmitFPClamp64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value, ScalarF64 min_value, ScalarF64 max_value) { - const Register ret{ctx.reg_alloc.LongDefine(inst)}; - ctx.Add("MIN.F64 {}.x,{},{};" - "MAX.F64 {}.x,{},{};", - ret, max_value, value, ret, ret, min_value); + Clamp(ctx, ctx.reg_alloc.LongDefine(inst), value, min_value, max_value); } void EmitFPRoundEven16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) { -- cgit v1.2.3