DirectX's FFP normalizes the zero vector to the zero vector, but GLSL normalizes them to all NaN.
This patch creates `ffp_normalize`, which normalizes vectors but has DirectX's behavior on 0 vectors. Further patches in this set switch other calls from GLSL's `normalize` to the 0-safe version.
This fixes [36564](https://bugs.winehq.org/show_bug.cgi?id=36564).
-- v2: wined3d: Use ffp_normalize in shader_glsl_ffp_vertex_lighting_footer. wined3d: Use ffp_normalize in shader_glsl_ffp_vertex_lighting. wined3d: Implement a zero-safe normalize function for FFP.
From: Petrichor Park ppark@codeweavers.com
DirectX's FFP normalizes the zero vector to the zero vector, but GLSL normalizes them to all NaN.
This patch creates ffp_normalize, which normalizes vectors but has DirectX's behavior on 0 vectors. Further patches in this set switch other calls from GLSL's normalize to the 0-safe version.
This fixes Wine-Bug: 36564. --- dlls/wined3d/glsl_shader.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 7dc0de1b596..c2a4a3fd659 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -9071,6 +9071,11 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); }
+ shader_addline(buffer, "\nvec3 ffp_normalize(vec3 n)\n{\n"); + shader_addline(buffer, " float lensq = dot(n, n);\n"); + shader_addline(buffer, " return lensq == 0.0 ? n : (n * inversesqrt(lensq));\n"); + shader_addline(buffer, "}\n"); + shader_addline(buffer, "\nvoid main()\n{\n"); shader_addline(buffer, "float m;\n"); shader_addline(buffer, "vec3 r;\n"); @@ -9132,7 +9137,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr }
if (settings->normalize) - shader_addline(buffer, "normal = normalize(normal);\n"); + shader_addline(buffer, "normal = ffp_normalize(normal);\n"); }
shader_glsl_ffp_vertex_lighting(buffer, settings, legacy_lighting); @@ -9173,11 +9178,11 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR: shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u]" - " * vec4(reflect(normalize(ec_pos.xyz), normal), 1.0);\n", i, i); + " * vec4(reflect(ffp_normalize(ec_pos.xyz), normal), 1.0);\n", i, i); break;
case WINED3DTSS_TCI_SPHEREMAP: - shader_addline(buffer, "r = reflect(normalize(ec_pos.xyz), normal);\n"); + shader_addline(buffer, "r = reflect(ffp_normalize(ec_pos.xyz), normal);\n"); shader_addline(buffer, "m = 2.0 * length(vec3(r.x, r.y, r.z + 1.0));\n"); shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u]" " * vec4(r.x / m + 0.5, r.y / m + 0.5, 0.0, 1.0);\n", i, i);
From: Petrichor Park ppark@codeweavers.com
--- dlls/wined3d/glsl_shader.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index c2a4a3fd659..2b3612aac6d 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -8894,7 +8894,7 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer shader_addline(buffer, "}\n"); continue; } - shader_addline(buffer, "dir = normalize(dir);\n"); + shader_addline(buffer, "dir = ffp_normalize(dir);\n"); shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx, legacy_lighting); shader_addline(buffer, "}\n"); } @@ -8915,8 +8915,8 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer { shader_addline(buffer, "if (dst.y <= ffp_light[%u].range)\n{\n", idx); } - shader_addline(buffer, "dir = normalize(dir);\n"); - shader_addline(buffer, "t = dot(-dir, normalize(ffp_light[%u].direction));\n", idx); + shader_addline(buffer, "dir = ffp_normalize(dir);\n"); + shader_addline(buffer, "t = dot(-dir, ffp_normalize(ffp_light[%u].direction));\n", idx); shader_addline(buffer, "if (t > ffp_light[%u].cos_htheta) att = 1.0;\n", idx); shader_addline(buffer, "else if (t <= ffp_light[%u].cos_hphi) att = 0.0;\n", idx); shader_addline(buffer, "else att = pow((t - ffp_light[%u].cos_hphi)" @@ -8946,7 +8946,7 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer if (!settings->normal) continue; shader_addline(buffer, "att = 1.0;\n"); - shader_addline(buffer, "dir = normalize(ffp_light[%u].direction.xyz);\n", idx); + shader_addline(buffer, "dir = ffp_normalize(ffp_light[%u].direction.xyz);\n", idx); shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx, legacy_lighting); }
@@ -8956,7 +8956,7 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer if (!settings->normal) continue; shader_addline(buffer, "att = 1.0;\n"); - shader_addline(buffer, "dir = normalize(ffp_light[%u].position.xyz);\n", idx); + shader_addline(buffer, "dir = ffp_normalize(ffp_light[%u].position.xyz);\n", idx); shader_glsl_ffp_vertex_lighting_footer(buffer, settings, idx, legacy_lighting); }
From: Petrichor Park ppark@codeweavers.com
--- dlls/wined3d/glsl_shader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 2b3612aac6d..1d98255ea70 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -8835,9 +8835,9 @@ static void shader_glsl_ffp_vertex_lighting_footer(struct wined3d_string_buffer shader_addline(buffer, "diffuse += clamp(dot(dir, normal), 0.0, 1.0)" " * ffp_light[%u].diffuse.xyz * att;\n", idx); if (settings->localviewer) - shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n"); + shader_addline(buffer, "t = dot(normal, ffp_normalize(dir - ffp_normalize(ec_pos.xyz)));\n"); else - shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, -1.0)));\n"); + shader_addline(buffer, "t = dot(normal, ffp_normalize(dir + vec3(0.0, 0.0, -1.0)));\n"); shader_addline(buffer, "if (dot(dir, normal) > 0.0 && t > 0.0%s) specular +=" " pow(t, ffp_material.shininess) * ffp_light[%u].specular * att;\n", legacy_lighting ? " && ffp_material.shininess > 0.0" : "", idx);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=135325
Your paranoid android.
=== debian11b (64 bit WoW report) ===
d3d11: d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 0.500000, clamp 0.000000: Got depth 4.99374978e-003, expected 4.99999989e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 0.500000, clamp -0.000010: Got depth 4.99374978e-003, expected 4.99999989e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 0.500000, clamp 0.000010: Got depth 2.50997487e-003, expected 2.50999994e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 1.000000, clamp 0.000000: Got depth 7.48750009e-003, expected 7.49999983e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 1.000000, clamp -0.000010: Got depth 7.48750009e-003, expected 7.49999983e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 1.000000, clamp 0.000010: Got depth 2.50997487e-003, expected 2.50999994e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 2.000000, clamp 0.000000: Got depth 1.24749998e-002, expected 1.24999997e-002. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 2.000000, clamp -0.000010: Got depth 1.24749998e-002, expected 1.24999997e-002. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 2.000000, clamp 0.000010: Got depth 2.50997487e-003, expected 2.50999994e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 128.000000, clamp 0.000000: Got depth 6.40899956e-001, expected 6.42499986e-001. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 128.000000, clamp -0.000010: Got depth 6.40899956e-001, expected 6.42499986e-001. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 128.000000, clamp 0.000010: Got depth 2.50997487e-003, expected 2.50999994e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 1000.000000, clamp 0.000010: Got depth 2.50997487e-003, expected 2.50999994e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 10000.000000, clamp 0.000010: Got depth 2.50997487e-003, expected 2.50999994e-003. d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 0.500000, clamp 0.000000: Got value 0x14745 (4.99373721e-003), expected 0x147ae (4.99999570e-003). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 0.500000, clamp -0.000010: Got value 0x14745 (4.99373721e-003), expected 0x147ae (4.99999570e-003). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 0.500000, clamp 0.000010: Got value 0x8528f (3.25097479e-002), expected 0x85293 (3.25099863e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 1.000000, clamp 0.000000: Got value 0x1eab3 (7.48747634e-003), expected 0x1eb85 (7.49999331e-003). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 1.000000, clamp -0.000010: Got value 0x1eab3 (7.48747634e-003), expected 0x1eb85 (7.49999331e-003). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 1.000000, clamp 0.000010: Got value 0x8528f (3.25097479e-002), expected 0x85293 (3.25099863e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 2.000000, clamp 0.000000: Got value 0x33190 (1.24750147e-002), expected 0x33333 (1.24999890e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 2.000000, clamp -0.000010: Got value 0x33190 (1.24750147e-002), expected 0x33333 (1.24999890e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 2.000000, clamp 0.000010: Got value 0x8528f (3.25097479e-002), expected 0x85293 (3.25099863e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 128.000000, clamp 0.000000: Got value 0xa41204 (6.40899956e-001), expected 0xa47ae0 (6.42499983e-001). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 128.000000, clamp -0.000010: Got value 0xa41204 (6.40899956e-001), expected 0xa47ae0 (6.42499983e-001). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 128.000000, clamp 0.000010: Got value 0x8528f (3.25097479e-002), expected 0x85293 (3.25099863e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 1000.000000, clamp 0.000010: Got value 0x8528f (3.25097479e-002), expected 0x85293 (3.25099863e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 10000.000000, clamp 0.000010: Got value 0x8528f (3.25097479e-002), expected 0x85293 (3.25099863e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 0.500000, clamp 0.000000: Got value 0x28e (9.97940078e-003), expected 0x290 (1.00099184e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 0.500000, clamp -0.000010: Got value 0x28e (9.97940078e-003), expected 0x290 (1.00099184e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 1.000000, clamp 0.000000: Got value 0x331 (1.24666207e-002), expected 0x334 (1.25123980e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 1.000000, clamp -0.000010: Got value 0x331 (1.24666207e-002), expected 0x334 (1.25123980e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 2.000000, clamp 0.000000: Got value 0x476 (1.74258035e-002), expected 0x47b (1.75020974e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 2.000000, clamp -0.000010: Got value 0x476 (1.74258035e-002), expected 0x47b (1.75020974e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 128.000000, clamp 0.000000: Got value 0xa411 (6.40894175e-001), expected 0xa47a (6.42496347e-001). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 128.000000, clamp -0.000010: Got value 0xa411 (6.40894175e-001), expected 0xa47a (6.42496347e-001).
This fixes Wine-Bug: 36564.
This isn't quite right either, I'm afraid, you want something like this commit message as an example:
https://source.winehq.org/git/wine.git/commitdiff/8ab7120badb68519eb3a76ad67...