PDA

View Full Version : GLSL Bug with array indexing on G80



Cyril
04-04-2007, 04:18 AM
Hi,
I am working on a stackered GPU ray marching (into octree) on G80 and I encounter a strange bug with GLSL. I am only drawing a cube and my fragment shader produce that (What I name "Behavior 1") :
http://www.icare3d.org/PUBLIC/BugGLSL1a.png
It looks like bad initialized variables but I checked that and I am not in that case, or not explicitly in the GLSL code. I suspected problem when indexing dynamically an array because everything work fine when indexing is made statically. But I find that there is a strange behavior on the initialization of a variable. When initialized with 0.0, it seems to act as if it wasn't initialized, but when initializing with very small number it works fine. I simplified my code in maximum to isolate the problem, here is the code of the fragment shader:

#version 120
#extension GL_EXT_gpu_shader4 : enable

varying vec4 viewDir;

struct LevelInfo{
ivec3 curVoxel;

vec3 tMax; //XYZ

//Unused: But Behavior 3 when deleted//
vec3 delta;
vec3 entryPos;
ivec3 coords;
};

void main(void)
{

int travLevel;
LevelInfo travStack[10];
float tMaxOK[3];

vec4 accCol=vec4(0.0,0.0,0.0, 0.0);

vec3 ray=normalize(viewDir.xyz);

travLevel=0; //Only index 0 should be used
travStack[travLevel].curVoxel=ivec3(0,0,0); //Start at 0
travStack[travLevel].tMax=ray; //We will accumulate that just for testing purpose

tMaxOK[travLevel]=0.0; //Behavior 1: Initialization with 0 of the only used element
// tMaxOK[travLevel]=0.0000001; //Behavior 2: It works fine with that ! (Solution 1)

while(travLevel>=0){
if(travStack[travLevel].curVoxel.x<3 ){
//travLevel=0; //Behavior 2: Works fine also with explicit maintaining of the index to 0 (Solution 2), but it should always be equal to 0 here.

//Color accumulation from a value in the array
vec4 col;
col=vec4(abs(tMaxOK[travLevel]));
accCol=accCol+(1.0-accCol.a)*col;

tMaxOK[travLevel]=travStack[travLevel].tMax.x;
travStack[travLevel].curVoxel.x+=1;

}else{//Exit the loop when curVoxel >2
travLevel=-1; //With that we will exit the loop
}

}

//Set fragment color to accumulated color
gl_FragColor=accCol;
}The viewDir is only an interpolated view to vertex computed in vertex shader.

Here is the correct result (Behavior 2):
http://www.icare3d.org/PUBLIC/BugGLSL1b.png

I also get another strange thing when deleting unused member of the struct, more artifacts are produced (Behavior 3):
http://www.icare3d.org/PUBLIC/BugGLSL1c.png

I have tested with Forcewares 97.73, 97.92 and 101.02 under windows XP and the problem is present with each driver version.

If anybody have an idea...

Thank you in advance.

ropel
04-05-2007, 12:09 AM
I don't see what the problem is here, but I do see you're using the shader 4 extension. You should be really carefull when mixing float and integer values. I've noticed that enabling this extension results in less debug information when checking your GLSL for errors (you do check it right?). You might want to try to disable the extension to see if there are conversion errors?

(I also use a G80 card, without indexing problems)

Good luck

Cyril
04-05-2007, 05:25 AM
Hi,
I tried to disable the extension and I get no conversion error so I don't think the problem is here :-(
Thank you all the same for your help.

tanzanite
04-06-2007, 01:46 PM
I have seen this. Not sure it is the same thing ...

My version of it i made some years ago for reference:
http://img402.imageshack.us/img402/4872/funyp8.jpg

My theory is that the shader occilates hevely in some calculations (calculations near the maximum precision possible) with the result that the rasterized blocks get slightly different input which produces major differences in the result.

No time to check your source ... but i hope i at least did give you an idea what to look for.

Anyway: curious look into the inner workings of a gpu, huh ? ;) I can see the 2x2 part for dXdZ and bigger blocks that are used for memory access efficiency i quess ...

Hope i made sense with my crapy english.