Now that the gl_*Matrix is deprecated we need to supply the shaders with our own matrices via uniforms. So far so good.
Imagine I have the following part of a vertex shader:
...
uniform mat4 my_projection_mat;
uniform mat4 my_modelview_mat;
attribute vec3 my_vertex_pos;
...
gl_Position = (my_projection_mat * my_modelview_mat) * vec4(my_vertex_pos, 1.0);
...
My question is: Will the AMD driver perform the "my_projection_mat * my_modelview_mat" multiplication for every vertex? Or it will understand that this calculation needs to be done only once?
write simple test with one matrix and then two matrix and compare results.
EDIT: i tried write simple vertex shader into GPU Shader Analyzer.
attribute vec4 pos;
uniform mat4 proj;
uniform mat4 model;
uniform mat4 view;
void main() {
gl_Position = model * pos;
}
it return code with four instruction slots
if i add one matrix to model * proj * pos; for example it return much longer code. 33 instruction slots
but if i change it to model * (proj * pos) it return only 8 instruction slots and each added matrix add four instruction slots. but only if i enclose it into parenthese
view * (model * (proj * pos)).
In your example I'll test this:
gl_Position = ( proj * view * model ) * pos;
But from what you said the driver doen't see the optimization. I mean, it could calculate the ( proj * view * model ) once and use the result for every vertex. But I dont know if this kind of cross vertex optimiztions are applicable.
PS: Too bad that Shader Analyzer is for windows only
There is no such optimization right now. Actually the program is linked before uniforms are set, if the optimization as you said is applied, we have to re-link the program after we get to know the uniform values. We don't know if it will take more time or less time.
Frank
matrix multiplication is associative so
(model * view) * pos == model * (view*pos)
but second is much faster because it need only 32 operations in contrast for first witch need 80 operations. (vector is just special case of matrix with one column)
so enclose multiplication of vector with multiple matrix into parenthese like this
mat1 * (mat2 * (mat3 * (mat4 * vec)))