[Bug 15644] Morrowind: Waterplane/sprite flickering with ORM=fbo

wine-bugs at winehq.org wine-bugs at winehq.org
Thu Mar 12 13:11:45 CDT 2009


http://bugs.winehq.org/show_bug.cgi?id=15644





--- Comment #48 from Tobias Jakobi <liquid.acid at 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.


-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list