diff --git a/rpcs3/Emu/RSX/Common/GLSLCommon.h b/rpcs3/Emu/RSX/Common/GLSLCommon.h index d97b96c005..0339126a61 100644 --- a/rpcs3/Emu/RSX/Common/GLSLCommon.h +++ b/rpcs3/Emu/RSX/Common/GLSLCommon.h @@ -583,21 +583,42 @@ namespace glsl if (props.domain == glsl::program_domain::glsl_vertex_program && props.emulate_zclip_transform) { - OS << - "double rcp_precise(double x)\n" - "{\n" - " double scaled = x * 0.0009765625;\n" - " double inv = 1.0 / scaled;\n" - " return inv * 0.0009765625;\n" - "}\n" - "\n" - "vec4 apply_zclip_xform(const in vec4 pos, const in float near_plane, const in float far_plane)\n" - "{\n"; - - if (!props.emulate_depth_clip_only) + if (props.emulate_depth_clip_only) + { + // Declare rcp_precise. Requires f64 support in the drivers. + // This is required to handle precision drift during division for extended depth range. + OS << + "double rcp_precise(double x)\n" + "{\n" + " double scaled = x * 0.0009765625;\n" + " double inv = 1.0 / scaled;\n" + " return inv * 0.0009765625;\n" + "}\n" + "\n" + // Technically the depth value here is the 'final' depth that should be stored in the Z buffer. + // Forward mapping eqn is d' = d * (f - n) + n, where d' is the stored Z value (this) and d is the normalized API value. + "vec4 apply_zclip_xform(const in vec4 pos, const in float near_plane, const in float far_plane)\n" + "{\n" + " if (far_plane != 0.0)\n" + " {\n" + " double z_range = (far_plane > near_plane)? (far_plane - near_plane) : far_plane;\n" + " double inv_range = rcp_precise(z_range);\n" + " float d = float(pos.z * rcp_precise(pos.w));\n" + " float new_d = (d - near_plane) * float(inv_range);\n" + " return vec4(pos.x, pos.y, (new_d * pos.w), pos.w);\n" + " }\n" + " else\n" + " {\n" + " return pos;\n" // Only values where Z=0 can ever pass this clip + " }\n" + "}\n\n"; + } + else { OS << - " float d = float(pos.z * rcp_precise(pos.w));\n" + "vec4 apply_zclip_xform(const in vec4 pos, const in float near_plane, const in float far_plane)\n" + "{\n" + " float d = float(pos.z / pos.w);\n" " if (d < 0.f && d >= near_plane)\n" " {\n" " // Clamp\n" @@ -613,29 +634,9 @@ namespace glsl " return pos;\n" " }\n" "\n" - " return vec4(pos.x, pos.y, d * pos.w, pos.w);\n"; + " return vec4(pos.x, pos.y, d * pos.w, pos.w);\n" + "}\n\n"; } - else - { - // Technically the depth value here is the 'final' depth that should be stored in the Z buffer. - // Forward mapping eqn is d' = d * (f - n) + n, where d' is the stored Z value (this) and d is the normalized API value. - OS << - " if (far_plane != 0.0)\n" - " {\n" - " double z_range = (far_plane > near_plane)? (far_plane - near_plane) : far_plane;\n" - " double inv_range = rcp_precise(z_range);\n" - " float d = float(pos.z * rcp_precise(pos.w));\n" - " float new_d = (d - near_plane) * float(inv_range);\n" - " return vec4(pos.x, pos.y, (new_d * pos.w), pos.w);\n" - " }\n" - " else\n" - " {\n" - " return pos;\n" // Only values where Z=0 can ever pass this clip - " }\n"; - } - - OS << - "}\n\n"; return; } diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index b7bb43cd36..639b4beec2 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -715,6 +715,22 @@ private: // See https://bugs.freedesktop.org/show_bug.cgi?id=110970 rsx_log.fatal("RADV drivers have a major driver bug with LLVM 8.0.0 resulting in no visual output. Upgrade to LLVM version 8.0.1 or greater to avoid this issue."); } + else if (get_driver_vendor() == driver_vendor::NVIDIA) + { +#ifdef _WIN32 + // SPIRV bugs were fixed in 452.28 for windows + const u32 threshold_version = (452u >> 22) | (28 >> 14); +#else + // SPIRV bugs were fixed in 450.56 for linux/BSD + const u32 threshold_version = (450u >> 22) | (56 >> 14); +#endif + const auto current_version = props.driverVersion & ~0x3fffu; // Clear patch and revision fields + if (current_version < threshold_version) + { + rsx_log.error("Your current NVIDIA graphics driver version %s has known issues and is unsupported. Update to the latest NVIDIA driver.", + get_driver_version()); + } + } if (get_chip_class() == chip_class::AMD_vega) {