From 834c4bbfda6582a79d2027fa0e2ad9b53659588d Mon Sep 17 00:00:00 2001 From: coldhex Date: Wed, 9 Jul 2025 13:11:55 +0300 Subject: [PATCH] nv2a/gl: Work around an Nvidia geometry shader compiler bug This adds redundant computation to the simple geometry shader for winding testing based on the assumption that Nvidia GeForce compiler has a bug which may incorrectly detect a simple geometry shader as a passthrough shader. --- hw/xbox/nv2a/pgraph/gl/gpuprops.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/hw/xbox/nv2a/pgraph/gl/gpuprops.c b/hw/xbox/nv2a/pgraph/gl/gpuprops.c index 29cb1e7b0e..58b195e8c3 100644 --- a/hw/xbox/nv2a/pgraph/gl/gpuprops.c +++ b/hw/xbox/nv2a/pgraph/gl/gpuprops.c @@ -68,16 +68,21 @@ static const char *geometry_shader_source = "out vec3 fragColor;\n" "in vec3 v_fragColor[];\n" "\n" - "void emit_vertex(int index) {\n" - " gl_Position = gl_in[index].gl_Position;\n" - " fragColor = v_fragColor[0];\n" - " EmitVertex();\n" - "}\n" - "\n" "void main() {\n" - " emit_vertex(0);\n" - " emit_vertex(1);\n" - " emit_vertex(2);\n" + " for (int i = 0; i < 3; i++) {\n" + // This should be just: + // gl_Position = gl_in[i].gl_Position; + // fragColor = v_fragColor[0]; + // but we work around an Nvidia Cg compiler bug which seems to + // misdetect above as a passthrough shader and effectively + // replaces the last line with "fragColor = v_fragColor[i];". + // Doing redundant computation seems to fix it. + // TODO: what is the minimal way to avoid the bug? + " gl_Position = gl_in[i].gl_Position + vec4(1.0/16384.0, 1.0/16384.0, 0.0, 0.0);\n" + " precise vec3 color = v_fragColor[0]*(0.999 + gl_in[i].gl_Position.x/16384.0) + v_fragColor[1]*0.00005 + v_fragColor[2]*0.00005;\n" + " fragColor = color;\n" + " EmitVertex();\n" + " }\n" " EndPrimitive();\n" "}\n";