From fd3ecea21e271f1d5f2487ae0d2f825d4303d2b3 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 17 Dec 2025 11:11:46 +0300 Subject: [PATCH] rsx: Improve early-Z disablement mechanism --- rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp | 11 ++++------- rpcs3/Emu/RSX/RSXThread.cpp | 2 ++ rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp | 11 ++++------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index 6ef26db1e0..f8cc046569 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -335,15 +335,12 @@ void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS) OS << "\n" << " fs_main();\n\n"; - if ((m_prog.ctrl & RSX_SHADER_CONTROL_DISABLE_EARLY_Z) && - !(m_prog.ctrl & (CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT | RSX_SHADER_CONTROL_META_USES_DISCARD)) && - g_cfg.video.shader_precision != gpu_preset_level::low) + if (m_prog.ctrl & RSX_SHADER_CONTROL_DISABLE_EARLY_Z) { - // This is effectively unreachable code, but good enough to trick the GPU to skip early Z + // This is effectively pointless code, but good enough to trick the GPU to skip early Z OS << - "// Insert NOP sequence to disable early-Z\n" - "if (isnan(gl_FragCoord.z))\n" - " discard;\n\n"; + " // Insert pseudo-barrier sequence to disable early-Z\n" + " gl_FragDepth = gl_FragCoord.z;\n\n"; } glsl::insert_rop(OS, m_shader_props); diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 1b58bf787f..a353c34d94 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2242,6 +2242,8 @@ namespace rsx } if (sampler_descriptors[i]->is_cyclic_reference && + !(current_fragment_program.ctrl & (CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT | RSX_SHADER_CONTROL_META_USES_DISCARD)) && + !g_cfg.video.strict_rendering_mode && g_cfg.video.shader_precision != gpu_preset_level::low) { current_fragment_program.ctrl |= RSX_SHADER_CONTROL_DISABLE_EARLY_Z; diff --git a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp index 8ecc427f73..af2e60ec93 100644 --- a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp @@ -471,16 +471,13 @@ void VKFragmentDecompilerThread::insertMainEnd(std::stringstream & OS) OS << "\n" << " fs_main();\n\n"; - if ((m_prog.ctrl & RSX_SHADER_CONTROL_DISABLE_EARLY_Z) && - !(m_prog.ctrl & (CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT | RSX_SHADER_CONTROL_META_USES_DISCARD)) && - g_cfg.video.shader_precision != gpu_preset_level::low) + if (m_prog.ctrl & RSX_SHADER_CONTROL_DISABLE_EARLY_Z) { // This is effectively unreachable code, but good enough to trick the GPU to skip early Z + // For vulkan, depth export has stronger semantics than discard. OS << - "// Insert NOP sequence to disable early-Z\n" - " const uint rop_control = fs_contexts[_fs_context_offset].rop_control;\n" - " if (_test_bit(rop_control, 0))\n" - " discard;\n\n"; + " // Insert pseudo-barrier sequence to disable early-Z\n" + " gl_FragDepth = gl_FragCoord.z;\n\n"; } glsl::insert_rop(OS, m_shader_props);