PDA

View Full Version : GLSL shader - 2 "funny" things on ATI cards (again...)



AllForum
03-20-2013, 09:19 AM
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 :
- If I call a function in my vertex shader I have problems : some views are not drawn and on an old ATI X1300/X1550 the depth buffer is invalid (http://www.opengl.org/discussion_boards/showthread.php/181183-Problem-with-glReadPixels-on-a-part-of-a-view-on-ATI-cards?p=1248827&viewfull=1#post1248827)
- If I copy/paste the code of the function in the main() then all works well.

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

#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 :

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 :
#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;
}


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 :

First problem
[CODE]
#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;
}

carsten neumann
03-20-2013, 10:04 AM
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 ;)

AllForum
03-20-2013, 10:25 AM
Thanks for the answer.
I have renamed the function but I have the same result...

And I edited my post to add [code] tags ! ;)

carsten neumann
03-20-2013, 11:45 AM
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?).

tonyo_au
03-20-2013, 05:30 PM
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;)

AllForum
03-21-2013, 07:22 AM
@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.

skeezix6
03-21-2013, 12:05 PM
Ch*o m?ng b?n d?n v?i di?n d*n ! cám on b*i vi?t c?a b?n cùng nhau phát tri?n t?t di?n d*n

Are bots posting these? What is the point?

nuclear_bro
03-25-2013, 01:34 AM
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.

AllForum
03-25-2013, 10:15 AM
Thanks for the information concerning the varyings.
I tried to return a vec2 but I still have the problem...

AllForum
03-26-2013, 09:01 AM
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...