ATI Cat 6.8 GLSL vertex shader - glUniform4fvARB subtle breakage

For setting arrays of uniforms larger then 31:

BROKEN:

  
for(ind = 0 ; ind < array_len ; ind++)
{    
    // re-calc bone
    glUniform4fvARB(uniform_index + ind, 1, (GLfloat*)&(tmp[ind]));
}

WORKING:

  
// calc all bones to tmp array and set them in one API call
glUniform4fvARB(uniform_index, array_len, (GLfloat*)tmp);

NVIDIA does not suffer from the said problem.

Try caling glGetUniformLocation for “array[0]”, “array[1]” and so on.
I’m curious if all locations are really continous. I believe it’s not mentioned in the specs that they should be - I will check it later.

Speedy, replace the two words BROKEN and WORKING with WRONG and CORRECT. :wink:
Never assume any uniform index location you haven’t queried.
Although it’s kind of logical to have individual array element locations ordered in the uniform list it’s not granted.
Why it’s not working with arrays bigger than 31 on one vendor escapes me. I could have understood 10 being special which would break if locations returned to the user are ordered alphabetically.
Anyway, your second method is the correct and faster way.

You cannot do arithmetic on location IDs. And NVIDIA can’t stop you from doing this - its driver behavior is perfectly valid. Please read ARB_shader_objects specification.

Of course, if the indices are coincidentally continuous the “broken” code works coincidentally. But you should not rely on such things.

Yes, the continuous ID assumption was sloppy - it came to be because NVIDIA returns only 1 uniform string per uniform array, so I thought the returned size is actually the number of continuous IDs.

Anyways, when I checked the IDs on ATI they were continous, so the BROKEN code should have been working by chance - there is subtle breakage in the ATI driver after all. (funny, it proved to be very useful, this kind of sloppiness has very nasty compatibility repercusions in production)

Anyways, thanks for all the suggestions - much appreciated!

Originally posted by speedy:
Yes, the continuous ID assumption was sloppy - it came to be because NVIDIA returns only 1 uniform string per uniform array
Per the spec on glGetActiveUniform:

“There will be only one active uniform reported by the GL per uniform array.”

They useto return one for each array element - but thye fixed it in later drivers.

@sqrt[-1]: that’s possibly one more bug on the list for the ATI GLSL implementation.

Originally posted by speedy:
that’s possibly one more bug on the list for the ATI GLSL implementation.
Are you saying that ATI returns each array element? So for “float a[2]” you get two active uniforms a[0] and a[1]? Or the IDs are just continuous?

Both - Cat. 6.8 returns N active uniforms for N-length array, and the IDs are continuous.

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