diff --git a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp index 1d94690d8f28..c5141b7fe7f3 100644 --- a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp @@ -792,8 +792,10 @@ template std::string FragmentProgramDecompiler::GetSRC(T src) } // Warning: Modifier order matters. e.g neg should be applied after precision clamping (tested with Naruto UNS) + const bool precision_before_abs = precision_modifier == RSX_FP_PRECISION_SATURATE; + if (precision_before_abs) ret = ClampValue(ret, precision_modifier); if (src.abs) ret = "abs(" + ret + ")"; - if (precision_modifier) ret = ClampValue(ret, precision_modifier); + if (precision_modifier && !precision_before_abs) ret = ClampValue(ret, precision_modifier); if (src.neg) ret = "-" + ret; return ret; diff --git a/rpcs3/Emu/RSX/Program/GLSLInterpreter/FragmentInterpreter.glsl b/rpcs3/Emu/RSX/Program/GLSLInterpreter/FragmentInterpreter.glsl index 075cac01e77b..8d76fd6edf39 100644 --- a/rpcs3/Emu/RSX/Program/GLSLInterpreter/FragmentInterpreter.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLInterpreter/FragmentInterpreter.glsl @@ -83,6 +83,8 @@ layout(location=0) in vec4 in_regs[16]; #define RSX_FP_REGISTER_TYPE_CONSTANT 2 #define RSX_FP_REGISTER_TYPE_UNKNOWN 3 +#define RSX_FP_PRECISION_SATURATE 4 + #define CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT 0xe #define CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS 0x40 @@ -242,6 +244,11 @@ vec4 read_src(const in int index) ur1 = GET_INST_BITS(index + 1, 9, 8); vr0 = shuffle(vr0, ur1); + if (GET_INST_BITS(2, 19 + index * 3, 3) == RSX_FP_PRECISION_SATURATE) + { + vr0 = clamp(select(vr0, vr_zero, isnan(vr0)), 0., 1.); + } + // abs if (index == 0) {