ATI problem with GLSL arrays?

I’m having compile issues with the following shader. On nVidia Geforce 8 there is no problem, but on a Radeon 4850 with Cat 9.2 (and previous) using a GL 2.1 context, the following does not compile. Even using ATI’s GPU Analyser tool - it also shows a problem with accessing the array. Not sure why. Bug ?

uniform sampler2D blursrc;

varying vec2 texCoord;

float texScaler = 1.0/256.0;
float texOffset = -0.5/256.0;

vec4 gaussFilter[7];

void main(void)
{
vec4 color = vec4(0.0,0.0,0.0,0.0);

gaussFilter[0] = vec4(-3.0, 0.0, 0.0, 1.0/64.0);
gaussFilter[1] = vec4(-2.0, 0.0, 0.0, 6.0/64.0);
gaussFilter[2] = vec4(-1.0, 0.0, 0.0, 15.0/64.0);
gaussFilter[3] = vec4( 0.0, 0.0, 0.0, 20.0/64.0);
gaussFilter[4] = vec4( 1.0, 0.0, 0.0, 15.0/64.0);
gaussFilter[5] = vec4( 2.0, 0.0, 0.0, 6.0/64.0);
gaussFilter[6] = vec4( 3.0, 0.0, 0.0, 1.0/64.0);

int i;
for (i=0;i<7;i++)
{
color += texture2D(blursrc,vec2(texCoord.x + gaussFilter[i].x * texScaler + texOffset,
texCoord.y + gaussFilter[i].y * texScaler + texOffset)) * gaussFilter[i].w;
} // End for

color.a *= 2.0;

gl_FragColor = color;
}

The specific issue is:
color += texture2D(blursrc, … gaussFilter[i]

Can anyone else shed light on this?
This is preventing me from performing blurs and creating rotating billboards. Very fustraiting!

if GLSL 1.10, not possible (array access only through consts). only GLSL 1.20 and above.

I have tried with #Version 120 but makes no difference!
I have a billboard vertex shader which access an array (actually a view matrix) using a 3rd texture coord.
Works nicely on nVidia (of course!)

[b]varying vec2 texCoord0;
varying vec3 texCoord1; //shading group centre position, w= scale
varying vec4 vertex;
varying vec4 basecolor;
uniform mat4 viewmatrix;
uniform vec3 camerapos;

void main()
{
// Set tex coord. Flip the Y-coord - DDS textures are upside down
texCoord0 = vec2 (gl_MultiTexCoord0.s, 1.0 - gl_MultiTexCoord0.t);
texCoord1 = vec3 (gl_MultiTexCoord1.xyz); //pass shading group position to PS

vertex = vec4 (gl_Vertex.xyz + (viewmatrix[gl_MultiTexCoord0.z].xyz * gl_MultiTexCoord1.w ), 1.0);

// Tranform to clip space.
gl_Position = gl_ModelViewProjectionMatrix * vertex;

basecolor = gl_Color;
}[/b]

best solution ever is to just test it on some other driver version to be sure it’s a driver problem. your shader doesn’t look very long tough haven’t looked carefully at it. what error you get anyways?

try initializing the array outside of main() :

vec4 gaussFilter[7]={
vec4(-3.0, 0.0, 0.0, 1.0/64.0),
vec4(-2.0, 0.0, 0.0, 6.0/64.0),

};

With the last example I posted (the billboard vertex shader) GPU analyser gives the following error (as does a compile on the Radeon):

ERROR: 0:15: ‘[]’ : integer expression required
ERROR: compilation errors. No code generated.

With the first blur shader - get the following when compiling:

Fragment Shader not supported by HWERROR: 0:25: Not supported when use temporary array indirect index.
ERROR: 0:26: Not supported when use temporary array indirect index.
ERROR: 0:26: Not supported when use temporary array indirect index.

In ATi demo-code, they used uniform-arrays for such kernel-bins. The values for those kernels were uploaded with glUniform.
Otherwise, you just unroll >_<

In the billboard code, make the mat4 be vec4[4]. If that fails, too - unroll to “if(var==0)…; else if(var==1);…”

On the billboard vertex shader, I tried changing mat4 to vec4 viewmatrix[4] as you suggested. However, still get:
ERROR: 0:15: ‘[]’ : integer expression required
ERROR: compilation errors. No code generated.

I also tried a float uniform to access the array - same error.

The solution is to cast into an integer:
int test = int (gl_MultiTexCoord0.z);

…but surely the compiler can’t be right and force us to use integers? This would imply version 120 ? and would mean ATI have broken GLSL support for older versions ?

This is a pure glsl limitation and it is a shame, you can only index array with constant expressions up to glslang 1.3 (reading the spec at first, I don’t have got hardware that supports 1.3).

There are some cases where it is possible as Ilian suggested. This is when the compiler can unroll the loop. and put itself constant between the brackets.

On nvidia hardware like geforce 8 series it works only because the Cg compiler uses some special profiles to compile your code that is not ARB compliant.

EDIT:

You will see that it does not compile using Cg compiler and compile it yourself with the arbfp1 profile.