rsx/fp: Ease pressure on fragment shaders when emulating clamp16

- TODO: Option to completely skip clamping in some architectures as it is not needed in most games
- Mostly affects older GPUs that do not have access to native fp16
This commit is contained in:
kd-11 2019-06-08 13:15:54 +03:00 committed by kd-11
commit c655036920
2 changed files with 21 additions and 6 deletions

View file

@ -274,18 +274,18 @@ std::string FragmentProgramDecompiler::ClampValue(const std::string& code, u32 p
switch (precision) switch (precision)
{ {
case 0: case RSX_FP_PRECISION_REAL:
// Full 32-bit precision // Full 32-bit precision
break; break;
case 1: case RSX_FP_PRECISION_HALF:
return "clamp16(" + code + ")"; return "clamp16(" + code + ")";
case 2: case RSX_FP_PRECISION_FIXED12:
return "precision_clamp(" + code + ", -2., 2.)"; return "precision_clamp(" + code + ", -2., 2.)";
case 3: case RSX_FP_PRECISION_FIXED9:
return "precision_clamp(" + code + ", -1., 1.)"; return "precision_clamp(" + code + ", -1., 1.)";
case 4: case RSX_FP_PRECISION_SATURATE:
return "precision_clamp(" + code + ", 0., 1.)"; return "precision_clamp(" + code + ", 0., 1.)";
case 5: case RSX_FP_PRECISION_UNKNOWN:
// Doesn't seem to do anything to the input from hw tests, same as 0 // Doesn't seem to do anything to the input from hw tests, same as 0
break; break;
default: default:
@ -491,6 +491,11 @@ template<typename T> std::string FragmentProgramDecompiler::GetSRC(T src)
} }
} }
} }
else if (src1.input_prec_mod == RSX_FP_PRECISION_HALF)
{
// clamp16() is not a cheap operation when emulated; avoid at all costs
apply_precision_modifier = false;
}
ret += AddReg(src.tmp_reg_index, src.fp16); ret += AddReg(src.tmp_reg_index, src.fp16);

View file

@ -10,6 +10,16 @@ enum register_type
RSX_FP_REGISTER_TYPE_UNKNOWN = 3, RSX_FP_REGISTER_TYPE_UNKNOWN = 3,
}; };
enum register_precision
{
RSX_FP_PRECISION_REAL = 0,
RSX_FP_PRECISION_HALF = 1,
RSX_FP_PRECISION_FIXED12 = 2,
RSX_FP_PRECISION_FIXED9 = 3,
RSX_FP_PRECISION_SATURATE = 4,
RSX_FP_PRECISION_UNKNOWN = 5 // Unknown what this actually does; seems to do nothing on hwtests but then why would their compiler emit it?
};
enum fp_opcode enum fp_opcode
{ {
RSX_FP_OPCODE_NOP = 0x00, // No-Operation RSX_FP_OPCODE_NOP = 0x00, // No-Operation