GLSL and Loops?

In a GLSL shader that I’m working on, I’m currently using a pair of nested for-loops.

Both loops have a fixed–indeed, hard-coded–loop-count.

Conversely, the loop-index is used within the loop for certain calculations.

I’ve seen some mentions online, and seem to have some vague memory, that loops might be unwise in shaders–perhaps unsupported in some contexts? However, what I have is unclear to me. And so I thus ask:

Are loops such as I’ve described a potential problem in a GLSL shader? Might they simply not work, or malfunction, on some machines? Or slow down significantly on some machines? Or some other untoward thing?

Or is there nothing to worry about?

Looping in shaders used to be more problematic than it is today. Loops with fixed ranges are usually “unrolled” by a compiler anyways, so manual unrolling is usually not necessary.

One caveat is that with OpenGL/GLSL the compilation is handled by the driver, and not all drivers are equal. Some mobile OpenGL drivers are not very good at optimizing.

Note that loop unrolling requires a compile-time constant to be used as loop bound.

I don’t know what the hw requirements are for non-constant loop counters. I don’t have time right now to look into it, perhaps try the GLSL spec or the OpenGL wiki.

At the very least, for non-unrolled loops, the usual caveats of branching apply, ie. all shader invocations in an “invocation group” (a block of pixels/vertices that is processed simultaneously) will run as long as the longest invocation in that group, which is guaranteed to never be a problem if the loop bound is a uniform variable.

Thank you both! :slight_smile:

Okay, that’s reassuring! :slight_smile:

Hmm… How big a worry is this?

For the sake of clarity, here is one of my loops:
for (int i = 0; i < 8; i++)
I take it that this would qualify?

(The other loop is essentially the same, but with a different end-value, and of course a different variable.)

Thankfully I don’t believe that I have any such in my current shader-code!

Okay, that’s fair, and as with the above, reassuring. :slight_smile:

(I’m not doing anything that I couldn’t unroll manually, if called for, I do believe–but a loop is far more convenient to work with, especially when experimenting with values.)

Yes, that loop can be trivially unrolled by the compiler.

Ah, excellent–that’s very good to know! :slight_smile:

Thank you again! :slight_smile:

In my experience it also forces loop unrolling if inside the loop there is an assignment to an array, even if the array is indexed by the loop variable, which would ensure that successive iterations would not be in conflict.
So a command inside a loop such as someArray[i] = somevalue; would force the compiler to unroll it.

If anyone has any idea how to avoid this I would love to know.

1 Like