PDA

View Full Version : Uniform blocks optimized out



Antoine
08-31-2010, 02:58 AM
Hi,

I'm trying to create a program, based on 2 shaders:

- The first one contains a list of functions that use the content of a uniform block.
- The second one, which contains the main() method, also uses the same uniform block.

My shaders look like this:



layout (shared) uniform camera { // layout should not be necessary
mat4 localToScreen;
mat4 localToWorld;
vec3 worldCameraPos;
};

layout(location = 0) in vec3 vertex;

void projection() {
gl_Position = localToScreen * vec4(vertex, 1.0);
}

And the second shader:



layout (shared) uniform camera { // layout should not be necessary
mat4 localToScreen;
mat4 localToWorld;
vec3 worldCameraPos;
};

layout(location = 0) in vec3 vertex;

void projection(vec3 normal, out vec3 worldPos, out vec3 worldNormal);

void main() {
//shading stuff here that uses projection()
}


This worked fine when just using uniforms, but when trying to use UniformBlocks, i get a linker error that says that declaration of camera conflicts with previous declaration (C1038)...

So i checked what uniforms were available (By replacing uniform names with "camera1" and "camera2"), and it appears that every uniform in the block from the first shader gets optimized out, despite the shared layout specifier.



Also, members of a block can be optimized out if they are found by the implementation to not affect the result of the shader.

Is this because there is no main() in the first shader to affect?

Is this the correct behavior? Am I doing something wrong here?


Thanks in advance...
Antoine B.

Edit : I am using GLSL #version 400

hound
08-31-2010, 06:32 AM
Section 3.7 of the glsl 400 docs says:



More generally, it is an error to redeclare a variable, including those starting “gl_”.


So really you shouldn't be redeclaring uniforms or uniform blocks in the same shader (you say you have 2 shaders, but that's inaccurate: you have two source strings forming one shader). Just remove the definition in the second source file/string.

Antoine
09-01-2010, 12:50 AM
Hi,

It's actually two different compilation units, which are then attached inside the same program (i.e. 2 shaders, each compiled with glCompileShader).
Redeclaring a variable in the way you explain should lead to compilation error;

hound
09-01-2010, 05:22 AM
Ah, sorry.

Sounds like it might be a compiler / linker bug then.

Although I don't understand why you declare the uniform block in the first shader if you're not using it there? As you noted the compiler will just optimize it out (being shared should have no effect on this), but the linker error sounds like a bug.

Antoine
09-01-2010, 06:16 AM
Yeah we thought so.. We submitted this on the nvidia board, we'll se what they say.

The example shown here is a simplified version of what we do, and the first shader is used in several programs, which is why we need the UniformBlock there (plus, the layout qualifier "shared" _should_ avoid it to be optimized out, even if not used, at least that's what I understand from the specs - Also note that every uniform inside the block from shader1 gets "optimized" out).

A temporary quick fix for this can be the following:
- Either add a method that returns the content of the block inside shader1 and call it from shader2
- Or declare the block in shader2 and pass it in parameters when using methods from shader1..

which works fine, but is not as clean as the other option (although I don't think this really has an impact on performances).

Anyway, thanks !

MalcolmB
02-08-2011, 11:04 AM
Did you get any results from asking Nvidia about this? I'm getting the same issue.