Accurately count number of uniforms used

Hey, I’m trying to determine the number of uniforms used so I know how many more I can use without causing a compile error.

I have 6 active uniforms (returned from querying after compiling).

sampler2D
sampler2D
float
int
mat4[252]
mat4

So, adding all these up (and assuming min size of 4 per uniform because float uses up the same as a vec4).
4 + 4 + 4 + 4 + (16 * 252) + 16 = 4064
My card has 4096.
So I should be able to change the mat4[252] to a mat4[253], but I can’t, I get a compile error.

Any ideas what I’m doing wrong?

Samplers do not count against uniform limits.

Also, uniform limits do not work that way. Each non-vector basic type is 1 component. So a float is 1 component. A mat4, composed of 16 floats is 16 components. If your card is counting a float as a vec4, then it is doing it wrong.

Any ideas what I’m doing wrong?

There are a number of issues in GLSL with trying to accurately count uniforms. First, there’s the fact that some implementations do this wrong. Second, built-in uniforms take up space too, so they can count against you without you even knowing.

In general, if you’re getting a uniform count exceeded error, just accept it.

Sorry I have to disagree. On current hardware (nvidia atleast) uniforms are only addressable as groups of vec4s. For example a array of 100 floats will take up the same amount of usable uniforms as an array of 100 vec4s. They aren’t packed as tightly as we’d like. Try using an array of floats that is 1/2 the size of your max uniforms, it won’t work.

[quote]Any ideas what I’m doing wrong?

There are a number of issues in GLSL with trying to accurately count uniforms. First, there’s the fact that some implementations do this wrong. Second, built-in uniforms take up space too, so they can count against you without you even knowing.

In general, if you’re getting a uniform count exceeded error, just accept it. [/QUOTE]

Built in uniforms are returned by the query function, and are thus counted (the mat4 in my example is gl_ModelViewProjectionMatrix).

Just accepting it isn’t an answer, since errors are just non-standard strings so there’s no way for me to know at runtime what the cause of a compilation error was. These are shaders that end-users create, not shaders that I create pre-release.

Sorry I have to disagree. On current hardware (nvidia atleast) uniforms are only addressable as groups of vec4s.

The spec says that each float/int/etc is a separate component. So NVIDIA is wrong.

Try using an array of floats that is 1/2 the size of your max uniforms, it won’t work.

If NVIDIA cannot guarantee that they can offer this when they expose 4096 uniform components, then then should not advertise 4096 components. They should do what ATI does and advertise 1024.

These are shaders that end-users create, not shaders that I create pre-release.

Then you have to show the user the error message and allow them the opportunity to fix their shader.

Sorry I should have made it more clear, I’m not looking for the theoretical answer. I’m looking for a practical working solution to the deficiencies of modern driver implementations.

There isn’t one. You cannot ensure that any particular shader will compile just by looking at it and the various limits. You can guess, you can make some heuristics. But you cannot know for certain until you compile it.

The practical, working solution is to compile your shader and fix any errors you get.

Right, but after I compile it I should be able to accurately determine it’s uniform usage.

There is an answer to this, I’ll just have to ask Nvidia it seems.