Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion about the OpenGL invariant qualifier

Tags:

opengl

So I was going through the orange book (3rd edition) and I came across a passage in chapter 9 about the invariant qualifier. And it says:

The invariant qualifier instructs the compiler and linked to ignore expressions and functions that are not directly related to the computation of the output.

This passage comes after two similar snippets of code:

uniform mat4 MVPmatrix;
// ...

in vec4 MCVertex;
// ...

a(); // does not modify gl_Position, MVP or MCVertex

// ...
// Transform vertex to clip space
gl_Position = MVP * MCVertex;

and

uniform mat4 MVPmatrix;
// ...

invariant gl_Position;
in vec4 MCVertex;
// ...

a(); // does not modify gl_Position, MVP or MCVertex

// ...
// Transform vertex to clip space
gl_Position = MVP * MCVertex;

The book then goes on to state:

The first case may or may not compute the transformed positions in exactly the same way no matter what unrelated function or expression is linked to the shader. This can cause problems in rendering if a multipass algorithm is used to render the same geometry more than once.

Which has me confused. If a() in no way affects the variables involved in calculating the transformed position, then how would the computation vary? (And how exactly does adding invariant help with that?). And referring to the first quote, what exactly do they mean by "ignoring the unrelated functions" ? Do they just not get executed?

like image 241
Borgleader Avatar asked Sep 25 '13 00:09

Borgleader


2 Answers

The purpose of invariant is to make sure the computation you're doing will result in the same result always, no matter what the shader optimizer will do to the shader (notably across multiple shader compilations).

I find the phrasing of the orange book to be poor (and misleading, as you've noted). The GLSL specification (language 1.2) section 4.6 is much clearer:

In this section, variance refers to the possibility of getting different values from the same expression in different programs. For example, say two vertex shaders, in different programs, each set gl_Position with the same expression in both shaders, and the input values into that expression are the same when both shaders run. It is possible, due to independent compilation of the two shaders, that the values assigned to gl_Position are not exactly the same when the two shaders run. In this example, this can cause problems with alignment of geometry in a multi-pass algorithm. In general, such variance between shaders is allowed. When such variance does not exist for a particular output variable, that variable is said to be invariant.

and it goes on to explain that the invariant qualifier gets you guarantees to avoid this issue.

like image 55
Bahbar Avatar answered Oct 18 '22 10:10

Bahbar


invariant keyword is, (in short and in contrast to Bahbar's more detailed answer) more about very subtle computational differences that might appear in, as you've mentioned, multiple geometry passes.

Here's an example: You draw an arbitrary, weird (to make it harder) triangle on the screen. The rasterizer gets normalized vertices and calculates all the fragments that it occupies, then runs a fragment shader on it. Now, imagine you'd like to draw another triangle exactly on top of it, but 3 hours later, while your PC is submerged, the temperature drops and you eat a lunch in the meantime. You recompile the shaders then, and bam...

All of those potentially can impact the rasterizer. Shader optimizations might kick in and make minuscular changes to the output. Whilst still technically correct, the result doesn't necessarily have to be exactly the same as the first triangle, and "the problems" will be some pixel from the first one left over.

invariant ensures that a potentially slower approach is taken. I am not a driver architect, mind you, but in general that might mean a few additional state resets, cleanups, or sometimes state stack push/pops. Only then you're left with the "clean" computational state, and as long as your hardware is alright, the result should be exactly the same.

like image 35
Bartek Banachewicz Avatar answered Oct 18 '22 08:10

Bartek Banachewicz