http://bugs.winehq.org/show_bug.cgi?id=15644
--- Comment #48 from Tobias Jakobi liquid.acid@gmx.net 2009-03-12 13:11:44 --- Looks like the problem is consisting of two components.
The first thing is the handling of "optimizable code" by the ATI GLSL compiler.
What do I mean by that. Well, the problem is that one GLSL shader program (id #35 in Jan's latest log) doesn't get compile properly, because of the (already known) error:
Fragment shader(s) linked, vertex shader(s) linked. WARNING: 0:2: extension 'GL_ARB_draw_buffers' is not supported WARNING: built-in varying gl_TexCoord [1] has mismatched access semantics between the vertex and fragment shader ERROR: Varying gl_TexCoord[1] read in fragment shader, but not written
There are three shader objects linked to the program #35. These are #36, #37 and #38. I could identify #36 as the vertex shader and #38 as the fragment shader.
That is #38, the fragment shader: #version 120 #extension GL_ARB_draw_buffers : enable uniform vec4 PC[8]; uniform sampler2D Psampler0; uniform sampler2D Psampler3; vec4 T0 = gl_TexCoord[0]; vec4 T1 = gl_TexCoord[1]; vec4 T2 = gl_TexCoord[2]; vec4 T3 = gl_TexCoord[3]; vec4 R0; vec4 R1; vec4 tmp0; vec4 tmp1; uniform vec4 PLC5; uniform vec4 PLC1; void main() { T0.xyzw = (texture2D(Psampler0, T0.xy).xyzw); tmp0.x = dot(T2.xyz, (2.0 * (T0.xyz - 0.5))); tmp0.y = dot(T3.xyz, (2.0 * (T0.xyz - 0.5))); T3.xyzw = (texture2D(Psampler3, tmp0.xy).xyzw); T1.xyzw = (PC[2].xyzw * (2.0 * (T0.xyzw - 0.5))); R1.xyzw = (vec4(dot(T1.xyz, (2.0 * (gl_Color.xyz - 0.5))))); R0.xyz = (T3.xyz * PC[4].xyz); R0.w = ((R1.w * PLC1.w) + PLC1.w); R1.xyzw = ((2.0 * (gl_Color.xyzw - 0.5))); R0.xyz = (mix(R0.xyz, PC[6].xyz, R1.www)); R0.w = (R0.w * R0.w); R0.w = (R0.w + -PC[7].w); gl_FragData[0] = R0; float fogstart = -1.0 / (gl_Fog.end - gl_Fog.start); float fogend = gl_Fog.end * -fogstart; float Fog = clamp(gl_FogFragCoord * fogstart + fogend, 0.0, 1.0); gl_FragData[0].xyz = mix(gl_Fog.color.xyz, gl_FragData[0].xyz, Fog); }
The problematic line is "vec4 T1 = gl_TexCoord[1];" The compiler considers this reading from gl_TexCoord[1] even though this line could probably be optimized into "vec4 T1;" without the initialization through data from gl_TexCoord[1]. T1 is never read before it is fully overwritten through "T1.xyzw = (PC[2].xyzw * (2.0 * (T0.xyzw - 0.5)));"
Now taking a look at the vertex shader (#36): #version 120 uniform vec4 VC[107]; uniform vec4 posFixup; void order_ps_input(); vec4 R4; vec4 R5; vec4 R6; vec4 R7; vec4 R8; vec4 R9; attribute vec4 attrib0; attribute vec4 attrib1; vec4 tmp0; vec4 tmp1; void main() { gl_Position.x = (dot(attrib0.xyzw, VC[2].xyzw)); gl_Position.y = (dot(attrib0.xyzw, VC[3].xyzw)); gl_Position.z = (dot(attrib0.xyzw, VC[4].xyzw)); gl_Position.w = (dot(attrib0.xyzw, VC[5].xyzw)); R5.xyzw = (vec4(dot(attrib0.xyzw, VC[4].xyzw))); R5.xyzw = (R5.xyzw + -VC[54].xxxx); gl_FogFragCoord = ((-R5.x * VC[54].z) + VC[54].w); R4.xyzw = (-attrib0.xyzw + VC[6].xyzw); R9.xyzw = (R4.xyzw); R4.z = (VC[30].x); R4.w = (dot(R4.xyz, R4.xyz)); R4.w = (inversesqrt(R4.w)); R4.xyz = (R4.xyz * R4.www); R6.xyzw = (R4.xyzw); R6.z = (VC[30].y); R5.xyzw = (VC[30].xxzx); R8.xyzw = (R5.yzxw * R4.zxyw); R8.xyzw = ((-R4.yzxw * R5.zxyw) + R8.xyzw); R8.z = (VC[30].y); R7.xyzw = (R6.xyzw); R7.y = (R8.x); R8.x = (R6.y); R9.w = (dot(R9.xyz, R9.xyz)); R9.w = (inversesqrt(R9.w)); R9.xyz = (R9.xyz * R9.www); R9.z = (max(R9.z, -R9.z)); R5.xyzw = (VC[1].xyzw + -R9.zzzz); R5.xyzw = (R5.xyzw * R5.xyzw); R5.xyzw = (R5.xyzw * VC[30].yyyy); R7.z = ((R5.z * R4.x) + R7.z); R8.z = ((R5.z * R4.y) + R8.z); R7.xy = (R7.xy * VC[53].xy); R8.xy = (R8.xy * VC[53].xy); gl_TexCoord[2].xyzw = (R7.xyzw); gl_TexCoord[3].xyzw = (R8.xyzw); gl_FrontColor.xyzw = ((R9.xyzz * VC[30].yyyy) + VC[30].yyyy); gl_TexCoord[0].xy = (attrib1.xy); order_ps_input(); gl_Position.y = gl_Position.y * posFixup.y; gl_Position.xy += posFixup.zw * gl_Position.ww; gl_Position.z = gl_Position.z * 2.0 - gl_Position.w; }
As you can see gl_TexCoord[1] is never accessed (more important: written to) in the vshader. Just inserting a "gl_TexCoord[1] = vec4(0.0, 0.0, 0.0, 0.0);" line after "void main() {" solves the compiler error, but sadly the flickering remains.
However I suspect something else to be a more critical source of the flickering, that's the second component:
One of the first errors from OpenGL is this one: fixme:d3d:IWineD3DDeviceImpl_CreateSwapChain >>>>>>>>>>>>>>>>> GL_INVALID_OPERATION (0x502) from glDrawBuffer(GL_BACK) @ device.c / 1838
Later the console is flooded with these kind of errors: fixme:d3d:apply_draw_buffer >>>>>>>>>>>>>>>>> GL_INVALID_OPERATION (0x502) from glDrawBuffers() @ context.c / 1445
Please note that not "everything" is affected by the flickering. It's the ingame waterplane, the ingame menu and the main menu. And some part of the vegetation (leafage of trees e.g.). The main ingame geometry is unaffected.
Looks like that the flickering is happening because no backbuffer is existant for these parts. Which sounds logical: No backbuffer so everything is always rendered to GL_FRONT, resulting is vsync-like flickering artifacts.
Also note that the GL_BACK problem didn't always exist. It looks like it doesn't depend on the wine version, but on the version of the ATI driver. In comment #32 e.g. I can't see any of these messages (like the swapchain one) in the logs.