From 709e6729ad09d0bf308ee98c2a5feb718a8bf0e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 8 Oct 2026 13:07:13 +0200 Subject: [PATCH] GLES: Enable the clip planes the vertex shader actually writes The vertex shader puts min/max Z in clip distances 0 and 1 and the near plane in 2, but the program flags still followed an older layout and never enabled plane 2. Geometry crossing the near plane was then only depth clamped, and smeared across the screen (Hellboy, FIFA Soccer, Hoto no Ken frame dumps). Co-Authored-By: Claude Opus 5.5 --- GPU/GLES/ShaderManagerGLES.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index b43c87b522..096b35acdc 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -186,12 +186,15 @@ LinkedShader::LinkedShader(GLRenderManager *render, VShaderID VSID, Shader *vs, GLRProgramFlags flags{}; flags.supportDualSource = gstate_c.Use(GPU_USE_DUALSOURCE_BLEND); - if (!VSID.Bit(VS_BIT_IS_THROUGH) && gstate_c.Use(GPU_USE_DEPTH_CLAMP)) { - flags.useClipDistance0 = true; - if (VSID.Bit(VS_BIT_VERTEX_RANGE_CULLING) && gstate_c.Use(GPU_USE_CLIP_DISTANCE)) + // Must match the planes GenerateVertexShader writes: min/max Z in 0 and 1, the near plane in 2. + if (gstate_c.Use(GPU_USE_CLIP_DISTANCE)) { + if (!VSID.Bit(VS_BIT_IS_THROUGH)) { + flags.useClipDistance0 = true; flags.useClipDistance1 = true; - } else if (VSID.Bit(VS_BIT_VERTEX_RANGE_CULLING) && gstate_c.Use(GPU_USE_CLIP_DISTANCE)) { - flags.useClipDistance0 = true; + } + if (VSID.Bit(VS_BIT_USE_HW_TRANSFORM)) { + flags.useClipDistance2 = true; + } } program = render->CreateProgram(shaders, semantics, queries, initialize, nullptr, flags);