https://bugs.winehq.org/show_bug.cgi?id=8848
Paul Gofman gofmanp@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |gofmanp@gmail.com
--- Comment #34 from Paul Gofman gofmanp@gmail.com --- Created attachment 64674 --> https://bugs.winehq.org/attachment.cgi?id=64674 Compute 3-component norm for nrm instruction
I have tested the demo and could reproduce the problem: dark characters clearly visible while browsing through menus. The problem is reproducible only when 'Enable PS 2.0 shaders' game setting is on. While the setting is not directly changeable in the menu, one can enable or disable this setting individually in Swat4SPDemo.ini file.
The problem (with PS 2.0 shaders enabled of course, and all settings maxed out, when the problem is reproducible) can be worked around by setting UseGLSL to 'disabled' (and max GL version 1.0 so that GLSL gets actually disabled).
This is reproducible with apitrace recorded on Windows 7. GLSL shaders exhibit the problem when replaying apitrace, while switching to ARB shaders replay it without dark characters, like on Windows.
The relevant difference between ARB and GLSL shaders is translation of 'nrm' d3d shader opcode. ARB shader backend is using only 3 component for norm calculation (which is consistent with MSDN docs), while GLSL backend is using all 4. Here is one of PS 2.0 shaders which suffers from this:
---- ps_2_0 def c0 = 5.00000000e-01, 2.00000000e+00, 0.00000000e+00, 0.00000000e+00 def c6 = 1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00 dcl t[0].xy dcl t[1].xy dcl_pp t[2].xyz dcl v[0] dcl v[1] dcl_2d s[0] dcl_2d s[1] texld_pp r[0], t[0], s[0] texld_pp r[1], t[1], s[1] mad r[1].xyz, r[1].w, c[6], r[1] add_pp r[1].xyz, r[1], -c[0].x mul_pp r[1].xyz, r[1], c[0].y
nrm_pp r[2], t[2] ; This is the problematic instruction
dp3_sat_pp r[3], r[1], r[2] mul_pp r[3], r[3], v[0] add_pp r[3], r[3], v[1] mul_pp r[4], r[3], r[0] mul_pp r[4].xyz, r[4], c[0].y mov_pp r[4].w, r[0].w mov_pp oC[0], r[4] ----
This is how the norm is translated in ARB shader backend: DP3 TA.x, fragment.texcoord[2], fragment.texcoord[2]; SGE TA.y, -TA.x, ps_helper_const.x; MAD TA.x, ps_helper_const.y, TA.y, TA.x; RSQ TA.x, TA.x; MUL R2, fragment.texcoord[2], TA.x;
and in GLSL backend:
tmp0.x = dot(T2.xyzw.xyz, T2.xyzw.xyz); R2.xyzw = (tmp0.x == 0.0 ? vec4(0.0) : (T2.xyzw * inversesqrt(tmp0.x))); ------------
I am attaching a patch which fixes this issue with GLSL backend. This could use a test of course, I am likely going to prepare some.
I tested "dark characters" only, some comments above concern some potentially different problems observed inside the game, I did not go deep inside and don't know if this is actually the same problem or not.