1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-21 18:22:33 +01:00

rsx: Round up 8-bit ROP output on NVIDIA cards

- NV GPUs have a tendancy to be off by a very small margin, breaking rendering when greaterThan/lessThan checks are used.
- NOTE: Currently this setting is using the sRGB flag which indicates 8-bit output.
  Only one game is currently known to care about this behaviour so this is good enough for now.
This commit is contained in:
kd-11 2022-01-15 22:28:11 +03:00 committed by kd-11
parent f923eaf09a
commit c38ca21a81
4 changed files with 25 additions and 8 deletions

View File

@ -214,6 +214,7 @@ void GLFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS)
m_shader_props.low_precision_tests = ::gl::get_driver_caps().vendor_NVIDIA;
m_shader_props.disable_early_discard = !::gl::get_driver_caps().vendor_NVIDIA;
m_shader_props.supports_native_fp16 = device_props.has_native_half_support;
m_shader_props.srgb_output_rounding = ::gl::get_driver_caps().vendor_NVIDIA;
glsl::insert_glsl_legacy_function(OS, m_shader_props);
}

View File

@ -510,10 +510,10 @@ namespace glsl
OS <<
" else if (srgb_convert)\n"
" {\n"
" " << reg0 << ".rgb = clamp16(linear_to_srgb(" << reg0 << ")).rgb;\n"
" " << reg1 << ".rgb = clamp16(linear_to_srgb(" << reg1 << ")).rgb;\n"
" " << reg2 << ".rgb = clamp16(linear_to_srgb(" << reg2 << ")).rgb;\n"
" " << reg3 << ".rgb = clamp16(linear_to_srgb(" << reg3 << ")).rgb;\n"
" " << reg0 << " = round_to_8bit(f16vec4(linear_to_srgb(" << reg0 << ").rgb, " << reg0 << ".a));\n"
" " << reg1 << " = round_to_8bit(f16vec4(linear_to_srgb(" << reg1 << ").rgb, " << reg1 << ".a));\n"
" " << reg2 << " = round_to_8bit(f16vec4(linear_to_srgb(" << reg2 << ").rgb, " << reg2 << ".a));\n"
" " << reg3 << " = round_to_8bit(f16vec4(linear_to_srgb(" << reg3 << ").rgb, " << reg3 << ".a));\n"
" }\n";
}
else
@ -521,10 +521,10 @@ namespace glsl
OS <<
" else if (srgb_convert)\n"
" {\n"
" " << reg0 << ".rgb = linear_to_srgb(" << reg0 << ").rgb;\n"
" " << reg1 << ".rgb = linear_to_srgb(" << reg1 << ").rgb;\n"
" " << reg2 << ".rgb = linear_to_srgb(" << reg2 << ").rgb;\n"
" " << reg3 << ".rgb = linear_to_srgb(" << reg3 << ").rgb;\n"
" " << reg0 << " = round_to_8bit(vec4(linear_to_srgb(" << reg0 << ").rgb, " << reg0 << ".a));\n"
" " << reg1 << " = round_to_8bit(vec4(linear_to_srgb(" << reg1 << ").rgb, " << reg1 << ".a));\n"
" " << reg2 << " = round_to_8bit(vec4(linear_to_srgb(" << reg2 << ").rgb, " << reg2 << ".a));\n"
" " << reg3 << " = round_to_8bit(vec4(linear_to_srgb(" << reg3 << ").rgb, " << reg3 << ".a));\n"
" }\n";
}
}
@ -561,6 +561,20 @@ namespace glsl
OS << "#define _kill() discard\n\n";
}
if (!props.fp32_outputs)
{
OS << "// Workaround broken output rounding behavior\n";
if (props.srgb_output_rounding)
{
const auto scale = (props.supports_native_fp16) ? "float16_t(255.)" : "255.";
OS << "#define round_to_8bit(v4) (round(v4 * " << scale << ") / " << scale << ")\n\n";
}
else
{
OS << "#define round_to_8bit(v4) (v4)\n\n";
}
}
if (props.require_texture_ops)
{
OS <<

View File

@ -37,5 +37,6 @@ namespace glsl
bool low_precision_tests : 1;
bool disable_early_discard : 1;
bool supports_native_fp16 : 1;
bool srgb_output_rounding : 1;
};
};

View File

@ -251,6 +251,7 @@ void VKFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS)
m_shader_props.low_precision_tests = device_props.has_low_precision_rounding;
m_shader_props.disable_early_discard = vk::get_driver_vendor() != vk::driver_vendor::NVIDIA;
m_shader_props.supports_native_fp16 = device_props.has_native_half_support;
m_shader_props.srgb_output_rounding = vk::get_driver_vendor() == vk::driver_vendor::NVIDIA;
glsl::insert_glsl_legacy_function(OS, m_shader_props);
}