glUniform...what is it really doing?

I’ve got some questions as to what is happening behind the scenes, and what kind of behavior I can count on.

As an example, does glUniform4f simply upload a value to a hardware register? Additionally, are those registers cached per shader, such that if I set uniform 3 on shader X, then change to shader Y, then change back to shader X…uniform 3 would still be valid? If I change Sampler 2, will that be global for all shaders from that point on, or again is it saved off per-shader?

Does glUniform patch the shader binary itself causing costly operations, such as on a pixel shader on playstation 3?

The reason I’m asking is right now I keep my own cache of what I think all the uniforms are, and every time I change to a shader I reupload that cache, but if I can be assured of certain behaviors I’d like to avoid redundant uploads.

As an example, does glUniform4f simply upload a value to a hardware register?

It uploads the value to the program. Whether this means “hardware register” or something else is hardware and driver dependent. It’s an abstraction; the implementation details are hidden.

Additionally, are those registers cached per shader, such that if I set uniform 3 on shader X, then change to shader Y, then change back to shader X…uniform 3 would still be valid?

Uniforms are per-program state. They are stored in the program object. So just like textures don’t change just because you bound a new texture, program uniforms don’t change just because you’re using a different program.

Does glUniform patch the shader binary itself causing costly operations, such as on pixel shader on playstation 3.

It’s hardware dependent. It will do whatever it has to. The PS3 uses old GeForce 7xxx hardware, so I imagine GL would do something similar when running on that hardware.

Ok, so opengl has its own copies of all the uniforms current values for every shader. Sounds like I was doing some redundant work then.

Thanks for the response.

I honestly would not depend on any behaviour here.

If the spec doesn’t say it explicitly, then the fact that it works on some or even all hardware means nothing. The next revision of a driver may change all of that.

The only case where I’ve found this kind of thing to be ultra-reliable is the old glProgramEnvParameter–ARB function (and I certainly wouldn’t try to mix that with modern code) but in fairness I’m not up to speed with more recent versions of GLSL.

If the spec doesn’t say it explicitly

It does say explicitly. This is not some small point that is in question or debate. This is how programs have worked since ARB_shader_objects. Uniforms are program state.

There’s a tiny difference: OpenGL stores the uniforms for every program as Alphonse pointed out, but not for every shader !

A shader can be part of multiple programs, and a program can be built from multiple shaders.

Ok, so opengl has its own copies of all the uniforms current values for every shader. Sounds like I was doing some redundant work then.

Just to avoid further confusion, setting uniform data has no effect on any other shader program than the one that is currently in use! If no program object is currently in use, setting uniform data is an invalid operation.

Also if you fear you’re doing redundant work, try to establish which variables are actually constant and most likely won’t change during program execution. Then at init time set the uniforms one time and never change them until the program ends.

There’s a tiny difference: OpenGL stores the uniforms for every program as Alphonse pointed out, but not for every shader !

A shader can be part of multiple programs, and a program can be built from multiple shaders.
[/QUOTE]

I think he used the word shader instead of program by mistake.
In GL, they call it a program. You know, that thing that you give to glUseProgram.
And the vertex shader and fragment shader, they call these shaders.

Of course. That one of the main reasons I created my own cache, such that it doesn’t send values up to the shader program unless it is actually a change. As I alluded to earlier some hardware platforms do major operations for pixel shader uniform changes, while others don’t. One time long ago I literally had the exact same application run 30fps on one graphics card, and 3-5fps on another equally powerful card because the app was setting 40,000 pixel shader uniforms a frame. Once the 39,000+ redundant changes were caught it ran nicely. :smiley: Vert shader uniform uploads were as fast as you’d expect on either graphics chip.

Anyway, it’s always nice to know what the expected behaviours are, and I do kinda wish I could peak into the drivers just to see what kinda things happen on various generations of video cards.

You are correct sir.

40,000 pixel shader uniforms

That’s shocking, somehow. :wink: May I ask what purpose your shader serves?

That was over a whole frame, involving several dozen different shaders. Figure 5,000 objects, each with 4-10 material properties? Wasn’t exactly that simple, but you get the idea how it can all add up.