I'm writing a fragment shader for WebGL(GLSL ES 1.0) using the latest version of Chrome(and Firefox), and I wrote an iterative algorithm.
So first of all, I found out the hard way that the length of the loop is quite restricted (doc says it must be guessable at compile-time, which means it must be a constant or very close).
In addition, I must write a (for
, since it's the only one which must be implemented according to the standard) loop that's potentially long but that breaks almost every time before the end.
Now, I've noticed that if I set a higher maximum number the compilation and linking of the shader takes alot more time. So, unless I'm wrong, the compiler does loop unwinding.
I'm not sure if anything can be done, but I've tried a few things and the compiler seems also to inline functions, even when called in loops.
I don't feel like it's normal for a shader to take a whole minute to compile for just about a hundred iterations of a loop. Or am I doing the wrong thing? Is a hundred iterations in a fragment shader way too much for a GPU? Because it seems to run just fine after it has compiled.
This is one of the unfortunate realities of GLSL. It would be great if we could do an offline compile and send in bytecode, or if we had the ability to specify flags at compile time or so on, but that's just not how the spec works. You are entirely at the mercy of the driver manufacturer. If NVIDIA/ATI thinks loop unrolling is good for you, your loop is gonna get unrolled.
I do question what it is that you are doing that requires so much looping, though. Shaders are not really the right place to be doing super complex looping or branching calculations. You'll certainly take a performance hit for it. If you're not worried about realtime performance, then perhaps a large compile hit at the start of your program isn't so bad. If you are concerned about the rendering speed of your app then you likely need to re-evaluate your shaders complexity.
You mention the shader taking more than a minute to compile a loop with a maximum of only about 100 iterations, and this makes me think your problem could be related to ANGLE.
ANGLE is a piece of software embedded in WebGL-capable browsers on the Windows OS, that takes your GLSL shader and translates it at runtime into a Direct3D HLSL shader. The thinking is that most Windows machines have newer Direct3D drivers compared to their OpenGL drivers, so the default behavior is to convert everything to D3D. In my experience this can be slow, particularly with long loops as you describe, although it's needed by many Windows users, particularly ones with Intel-based graphics.
If you're running Windows and you have good-quality OpenGL drivers, such as reasonably new ones from nVidia or AMD, you can try disabling ANGLE to see if it fixes your problem. On Google Chrome this is done by editing your Chrome icon to add --use-gl=desktop
as a command-line parameter (in the 'target' field of the icon) and restart the browser. For Firefox, you can visit about:config
and type webgl
into the search box, and look for webgl.prefer-native-gl
and set that to true.
Try your shader again with ANGLE disabled, and compile times may be improved. Keep in mind this is only a Windows issue, so editing these settings on other platforms has no effect, but I believe all other platforms all use native OpenGL directly.
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