Does the spec say anything about how fast/efficient it is? No.
You’re relying on driver behavior in this case because you have no choice. You can’t write a driver (or, at least, not one that’s going to beat the IHV one in performance), so there’s no point in debating what performance you’re getting out of it.
You have a choice about uniform protection.
Exactly, it just makes the OpenGL calls for me, and that’s exactly why it will work on ATi, Intel, etc…
Work? Yes. Work well? There’s no guarantees on that.
Remember: the shader code that Cg generates is optimized for nVidia hardware; that’s how nVidia writes it. So, while you may not be using uniforms improperly, you certainly stand a pretty good chance of losing performance on non-nVidia hardware.
The problem with this is that let’s say I’m using the same shader in different places (eg. my font shader). Now I have to share this UniformInfo object between all of them (they could even be in separate DLLs!), otherwise the UniformInfo object will think that it’s unchanged, when in fact it is…
Hence the poorly-structured code.
Your main code shouldn’t be thinking in terms of low-level constructs like “shaders”, let alone uniforms within them. They should be dealing with objects that make sense to them. If you change a font’s color, you should change the font object’s color. The fact that this will, behind the scenes, affect some kind of uniform within a shader is totally irrelevant.
Plus, uniforms (or rather, uniform blocks) are bound to the shader that they are used in. As such, they belong with that shader. Conceptually, you should be able to say, “shader->GetUniformBlock()->SetValue()”. The uniform data is an intrinsic part of the shader.