I have an OpenGL shader written in glsl. I have a globally defined array at the top of the header like this:
const int permutations[256] = int[256](
64 , 34 , 36 , 137 , 120 , 122 , 246 , 46 , 79 , 10 , 37 , 181,
...
);
When I start the program, it is extremely slow, meaning I have only like 1 frame per second, when displaying a simple teapot using the shader.
However, as soon as I remove the "const" from the above declaration, everything works fine, and I'm back at interactive frame rates.
So, the "problem" is actually already solved... but I was wondering, why this could be the case? Very counterintuitive, as in my experience, using consts usually makes programs faster.
I actually tried to use a Uniform first instead of the const int array, with exactly the same code everywhere else. However, in this case compiling the shader crashes with:
Internal error: assembly compile error for fragment shader at offset
34609:
-- error message -- line 651, column 22: error: invalid local parameter number
Under GLSL version 3.30, Sampler arrays (the only opaque type 3.30 provides) can be declared, but they can only be accessed by compile-time integral Constant Expressions. So you cannot loop over an array of samplers, no matter what the array initializer, offset and comparison expressions are.
When an array indexing expression, including struct field member accesses, results in an opaque types, the standard has special requirements on those array indices. Under GLSL version 3.30, Sampler arrays (the only opaque type 3.30 provides) can be declared, but they can only be accessed by compile-time integral Constant Expressions.
Under GLSL 4.00 and above, array indices leading to an opaque value can be accessed by non-compile-time constants, but these index values must be dynamically uniform. The value of those indices must be the same value, in the same execution order, regardless of any non-uniform parameter values, for all shader invocations in the invocation group.
Given the presence of this feature, arrays can be declared multidimensionally in GLSL: multidim is an array of 5 elements, where each element is an array of 2 vec3 elements. So multidim.length () is 5, while multidim [0].length () is 2. Arrays can also be declared like this: This may make things more clear. You can combine these:
That's very strange. Most probably you're having driver issues. I've ran included shader code on my Nvidia 540M under windows, and let it run in cycle. In that cycle I called shader program once and measured time (also I had checked with transform feedback if shader is working correctly). Most of cycles ended in 2-3 miliseconds, with some peaks at 25 ms. However removing const
identifier had no effect on performance. These are quite small values to measure, but from your description the performance hit of const
should be observable even here.
#version 150
const int permutations[256] = int[256](
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
...
246, 247, 248, 249, 250, 251, 252, 253, 254, 255
);
flat out int num1[32];
void main(){
for(int i = 0; i < 32; i++){
num1[i] = (permutations[2*i]+permutations[2*i+1])*(permutations[2*i+2]+permutations[2*i+3]);
}
}
Maybe if you wouldn't mind I could try to run your program on my hardware, but it would have to be compiled for windows and please include all dynamic libraries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With