Problem using uniform arrays on ATI

I’ve run into problems using uniform arrays. I’m currently using a Radeon 9800 Pro with Catalyst 4.7.

There’s actually 2 problems:

if a declare in a fragment shader e.g.

uniform float f[3];

I can set the 1st value using:

float FDataPtr[3] = ...;
glUniform1fvARB(f_loc, 1, FDataPtr);

but If I’m setting more vars, e.g.

glUniform1fvARB(f_loc, 2, FDataPtr);

everything is undefined!!

just including the code of the orange book P.189:

struct 
{
	struct 
	{
		float a;
		float b[10];
	} c[2];
	vec2 d;
} uniform e;

I get a compile error.

Can anyone shed some light on these issues? thnx

I can help you with your second problem. This is an error of the book, visit the site of the book:
Orange Book´s Page

Do you have a sample app showing the first problem? I can’t reproduce the problem, everything works as expected here. If you got any sample app, send it to me at epersson ‘at’ ati.com and I’ll take a look at it.

on a similar note right now I have this in my vertex shader:

 #define MAX_BONES 60
struct QuatPos
{
   vec4 q;
   vec3 p;
};

uniform QuatPos bones[MAX_BONES]; 

and in c++ code I call:

 location = glGetUniformLocationARB( shader->GetProgramObj(), "bones[0].q.x" ); 

after which location = -1

Which I think is the correct going by syntax listed at SGI's OpenGL Extension Registry under issue 32.

edit
I suppose I should mention I’m using a Radeon Mobility 9700 with Omega 2.5.58 drivers.

 location = glGetUniformLocationARB( shader->GetProgramObj(), "bones[0].q.x" ); 

The above code would return -1 since bones[0].q.x does not exist as a uniform.

This code will work

 location = glGetUniformLocationARB( shader->GetProgramObj(), "bones[0].q" ); 
  
glUniform1fvARB(f_loc, 2, FDataPtr);

What does the aboev line do? Maybe you should update the entire array else it must screw up.

  
glUniform1fvARB(f_loc, 3, FDataPtr);

Also keep in mind that if the GLSL compiler has optimized out the uniform (ie. it is not used) you may also get -1.

Forgot to mention, I verified a bug with arrays that has been optimized by the driver. The spec states that you can pass a uniform array larger than the actual size of the uniform and the driver should just silently ignore all data beyond the end of the array. The driver however returns GL_INVALID_VALUE instead without updating the uniform values. You can work around the problem in the mean time by either querying what the length of the array is and match this size in the glUniform call, or you can simply ensure you’re using the last element of the list so that the driver doesn’t shorten it.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.