GLSL shader - 2 "funny" things on ATI cards (again...)

Hello,

I would like to know if you see huge errors in my code.
It’s incomprehensible for me…

1- If I call a function in my vertex shader some views are not drawn. If I copy/paste the code of the function in the main then all works well.
2- If I use a varying float variable in a fragment shader I have no more dashed lines. If I comment the line then all works well…

First problem :

Here is the code : the green code works, the red code does not work.

[i]#version 110

varying vec3 N;
varying vec4 v;
varying vec2 glTexCoord;
uniform int TexGenMode = 0;
uniform int bIsTexture = 0;

// the function
void glTexGen( const in int textureUnit,
const in int genMode,
const vec4 ecPosition,
out vec2 _glTexCoord)
{
if (genMode == 0)
{
_glTexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);
return;
}
if (genMode == 1) // 1 == GL_EYE_LINEAR
{
_glTexCoord.s = dot(gl_Vertex, gl_ObjectPlaneS[textureUnit]);
_glTexCoord.t = dot(gl_Vertex, gl_ObjectPlaneT[textureUnit]);
return;
}
if (genMode == 2) // 2 == GL_OBJECT_LINEAR
{
_glTexCoord.s = dot(ecPosition, gl_EyePlaneS[textureUnit]);
_glTexCoord.t = dot(ecPosition, gl_EyePlaneT[textureUnit]);
return;
}
}

void main(void)
{
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;

v = gl_ModelViewMatrix * gl_Vertex;
N = normalize(gl_NormalMatrix * gl_Normal);

#if 0
if (bIsTexture != 0)
{
if (TexGenMode == 0) // ne pas toucher
{
glTexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);
}
if (TexGenMode == 1) // 1 == GL_EYE_LINEAR
{
glTexCoord.s = dot(gl_Vertex, gl_ObjectPlaneS[0]);
glTexCoord.t = dot(gl_Vertex, gl_ObjectPlaneT[0]);
}
if (TexGenMode == 2) // 2 == GL_OBJECT_LINEAR
{
glTexCoord.s = dot(v, gl_EyePlaneS[0]);
glTexCoord.t = dot(v, gl_EyePlaneT[0]);
}
}
#else
if (bIsTexture != 0)
glTexGen(0, TexGenMode, v, glTexCoord);
#endif

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

}[/i]

Second problem :

On an ATI X1300/X1550, with the basic shaders below, glLineStipple has no effect if I uncomment the red line !
I do not use this variable !
In my full shader I need a variable to compute lighting : so I have light but I have no more dashed lines…

Vertex shader :
[i]#version 110
varying vec3 N;
varying float vx;

void main(void)
{
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
vx = 1.0;
N = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}[/i]

Fragment shader :
#version 110
varying vec3 N;
varying float vx;

void main (void)
{
vec3 L = normalize(gl_LightSource[0].position.xyz);
float vvx = vx; // If I comment this useless line the card draws again dashed lines
vec3 R = normalize(-reflect(L,N));
gl_FragColor = vec4(1,0,0,1);
return;
}

For the first problem it seems a bug in my code somewhere because the problem is on several ATI cards.

For the second problem maybe it is a bug in the old driver (last driver : 2/2010). Or something in my code that generates the problem in the shaders.

gdebugger and AMD GPU ShaderAnalyser see no error.
So if you have an idea…

As nvidia understand my code I started to detest ati cards…

Edit : the same code without color but in

 tags :

[b]First problem[/b]

#version 110

varying vec3 N;
varying vec4 v;
varying vec2 glTexCoord;
uniform int TexGenMode = 0;
uniform int bIsTexture = 0;

// the function
void glTexGen( const in int textureUnit,
const in int genMode,
const vec4 ecPosition,
out vec2 _glTexCoord)
{
if (genMode == 0)
{
_glTexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);
return;
}
if (genMode == 1) // 1 == GL_EYE_LINEAR
{
_glTexCoord.s = dot(gl_Vertex, gl_ObjectPlaneS[textureUnit]);
_glTexCoord.t = dot(gl_Vertex, gl_ObjectPlaneT[textureUnit]);
return;
}
if (genMode == 2) // 2 == GL_OBJECT_LINEAR
{
_glTexCoord.s = dot(ecPosition, gl_EyePlaneS[textureUnit]);
_glTexCoord.t = dot(ecPosition, gl_EyePlaneT[textureUnit]);
return;
}
}

void main(void)
{
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;

v = gl_ModelViewMatrix * gl_Vertex;
N = normalize(gl_NormalMatrix * gl_Normal);

#if 0
if (bIsTexture != 0)
{
if (TexGenMode == 0) // ne pas toucher
{
glTexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);
}
if (TexGenMode == 1) // 1 == GL_EYE_LINEAR
{
glTexCoord.s = dot(gl_Vertex, gl_ObjectPlaneS[0]);
glTexCoord.t = dot(gl_Vertex, gl_ObjectPlaneT[0]);
}
if (TexGenMode == 2) // 2 == GL_OBJECT_LINEAR
{
glTexCoord.s = dot(v, gl_EyePlaneS[0]);
glTexCoord.t = dot(v, gl_EyePlaneT[0]);
}
}
#else
if (bIsTexture != 0)
glTexGen(0, TexGenMode, v, glTexCoord);
#endif

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

}



Second Problem :

Vertex shader :
#version 110
varying vec3 N;
varying float vx;

void main(void)
{
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
vx = 1.0;
N = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Fragment shader :
#version 110
varying vec3 N;
varying float vx;

void main (void)
{
vec3 L = normalize(gl_LightSource[0].position.xyz);
float vvx = vx; // If I comment this useless line the card draws again dashed lines
vec3 R = normalize(-reflect(L,N));
gl_FragColor = vec4(1,0,0,1);
return;
}

Quick questions/thought: aren’t all identifiers prefixed with “gl” considered reserved in GLSL, does using different names have any influence?

I’m afraid I haven’t read all the code, mostly because you did not put it in [ code]/[ /code] tags; I know color does not work then, but it would be sooo much easier to read :wink:

Thanks for the answer.
I have renamed the function but I have the same result…

And I edited my post to add

 tags ! ;)

Thanks! For your second problem I would agree that a driver bug is quite possible, especially since the interaction between something “exotic” like line stipple and shaders is probably not very well tested.
Off hand I don’t see anything wrong with your first shader, you could try to return a vec2 from your glTexGen function instead of assigning to a varying passed in via an “out” argument (maybe that is confusing the shader compiler?).



float vvx = vx;    // If I comment this useless line the card draws again dashed lines

I have found the AMD driver is very sensitive to unused code. I suspect their code optimiser is not very good at removing unwanted code.
I have solved a few shader errors by manually removing code that is no longer doing anything.

I suppose you could say it is my fault for leaving it there;)

@carsten neumann
I tried to return a vec2 from my function but that is not better…

@tonyo_au
I will check if I have unused variables.
I reproduced the problem with this simple unused float. But in my “real” shader I have to use this float…

Another information :
If I disable antialiasing (MSAA or the classical GL_*_SMOOTH) the first problem disappears…

As you did not see a big error in my code I will maybe post on an AMD forum to maybe have an explanation…

Thanks for your answers.

Are bots posting these? What is the point?

As for problem 1: maybe it’s not a good idea to use varyings as function out parameter. We had some inconveniences with ATI and Intel compilers throwing errors or even hanging on linking stage when playing similar tricks. Try to rewrite your glTexGen function to return vec2 value and then use it as init value for varying:

if (bIsTexture != 0)
  glTexCoord = glTexGen(0, TexGenMode, v);

Maybe this would help.

Thanks for the information concerning the varyings.
I tried to return a vec2 but I still have the problem…

A small update.

I tested with the condition always false.


if (bIsTexture != 0) // always false
   glTexCoord = glTexGen(0, TexGenMode, v);

So the function is not called. And I have the problem !
So it seems a problem with the generated code.

After the remarks concerning varying I have found a workaround for a HD5450 card. (a case in which the compiler works…)
But it does not work on FirePro V3750.

I don’t know how you do to write code that works on all cards…

So I will copy the code of the function in the main…