No dynamic branching in Fragment Shader (WebGL 1)

366 views
Skip to first unread message

Alecazam

unread,
Apr 16, 2014, 4:18:46 PM4/16/14
to webgl-d...@googlegroups.com
This is something that's been present on desktop/laptop hw for over a decade.  WebGL 1 could really use an extension to allow this to work with fragment shaders.  Fragment shader ints and loops can only be hard-coded to a constant.  I'm assuming that WebGL 2 will be the first way to access this (as per ES3).  I'm assuming that WebGL vertex shaders support dynamic and static branching properly.  The caller could always switch to a series of shaders for multiple loop constants, but at least on the majority of hardware looping is already supported.

Jeff Dash

unread,
Apr 16, 2014, 5:03:28 PM4/16/14
to webgl-d...@googlegroups.com
WebGL2 is the path forward for this. I don't think we're going to backport support to WebGL1.

-Jeff


On Wed, Apr 16, 2014 at 1:18 PM, Alecazam <al...@figma.com> wrote:
This is something that's been present on desktop/laptop hw for over a decade.  WebGL 1 could really use an extension to allow this to work with fragment shaders.  Fragment shader ints and loops can only be hard-coded to a constant.  I'm assuming that WebGL 2 will be the first way to access this (as per ES3).  I'm assuming that WebGL vertex shaders support dynamic and static branching properly.  The caller could always switch to a series of shaders for multiple loop constants, but at least on the majority of hardware looping is already supported.

--
You received this message because you are subscribed to the Google Groups "WebGL Dev List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to webgl-dev-lis...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Alecazam

unread,
Apr 16, 2014, 5:15:20 PM4/16/14
to webgl-d...@googlegroups.com
I actually found a nice workaround for WebGL 1 using break/continue that works quite well.   You can specify a fixed loop, and then break/continue to skip loop portions that you don't want.   It's certainly better to hardcode loop counts that are closer to what you need, but this lets one shader apply to several limiter values.

uniform float limiter;  // set this to 2.0

for (int i = -10; i < 10; ++i)  { // fixed count
  float t = float(i);
  if (abs(i) > limiter)
    continue;
   
  do some work...

Alecazam

unread,
Apr 16, 2014, 5:17:06 PM4/16/14
to webgl-d...@googlegroups.com
Make that abs(t).


On Wednesday, April 16, 2014 2:15:20 PM UTC-7, Alecazam wrote:
I actually found a nice workaround for WebGL 1 using break/continue that works quite well.   You can specify a fixed loop, and then break/continue to skip loop portions that you don't want.   It's certainly better to hardcode loop counts that are closer to what you need, but this lets one shader apply to several limiter values.

uniform float limiter;  // set this to 2.0

for (int i = -10; i < 10; ++i)  { // fixed count
  float t = float(i);
  if (abs(t) > limiter)

Jan Scheurer

unread,
Apr 16, 2014, 9:34:10 PM4/16/14
to webgl-dev-list
Why not just make that uniform an integer and save that abs call ;)


--
You received this message because you are subscribed to the Google Groups "WebGL Dev List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to webgl-dev-lis...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
dvlpn 3d stuff since ever

Alecazam

unread,
Apr 17, 2014, 1:54:32 PM4/17/14
to webgl-d...@googlegroups.com, lj1...@googlemail.com
It would save the cast, but not the abs.  It's a symmetric limiter about 0 and -/+10, setting the limiter to 2.0 limits that to +/-2.  I've had fragment shaders fail to compile with ivec2..4 (despite it also being possible on desktop for a decade or more), so I've avoided int for fragment4 uniforms in WebGL.  Also I would assume the comparisons are all done in float precision anyways in the ALU, so it's probably a wash.

Florian Bösch

unread,
Apr 18, 2014, 3:30:22 AM4/18/14
to webgl-d...@googlegroups.com
On Wednesday, April 16, 2014 11:03:28 PM UTC+2, Jeff Dash wrote:
WebGL2 is the path forward for this. I don't think we're going to backport support to WebGL1.

Is the constant expression restriction going away in WebGL 2? If so, how do you solve the DOS of a users machine with an endless loop? 

Alecazam

unread,
Apr 18, 2014, 12:18:27 PM4/18/14
to webgl-d...@googlegroups.com
Can't the compiler just fail the compile if that were the case?   It feels like uploading an int to control a loop is about doing less work on the GPU than having a fixed constant.   You can always do retina x a 64K fixed loop and exceed unrolling limits or exceed a given time interval.  DX/iOS just kill the process after 2s or 5s for a single draw.  A watchdog thread seems like the only way to avoid a DOS attack rather than artificially limiting shader flexibility. 

Kenneth Russell

unread,
Apr 19, 2014, 6:45:39 PM4/19/14
to webgl-d...@googlegroups.com
Denial-of-service issues are addressed in WebGL implementations using
the watchdog timeout implicitly specified in GL_ARB_robustness /
GL_EXT_robustness. A long-running draw call is supposed to be
terminated by the driver and a lost context notification delivered to
the application (in this case, the browser). Chrome addresses the DoS
issue by disallowing WebGL content from domains whose code may have
triggered a context loss, until the user explicitly accepts a prompt
allowing it to run again. This topic is covered in more detail in
http://www.khronos.org/webgl/security/#Denial_of_Service .

As Jeff pointed out, section 12.30 "Dynamic Indexing" in the GLSL ES
3.00.4 specification lifts most of the restrictions in OpenGL ES 2.0
and therefore WebGL 1.0. However, and unfortunately, in OpenGL ES 3.0,
arrays of samplers can only be indexed with
constant-integral-expressions. I don't know the reason for this
restriction. Perhaps an OpenGL ES extension could be defined which
would lift it, and that could then be exposed in WebGL.

-Ken

Alecazam

unread,
Apr 19, 2014, 7:50:36 PM4/19/14
to webgl-d...@googlegroups.com
Thanks for the links Ken.  I've seen the watchdog in the Firefox source.  I'm not looking for the fancy stuff like indexed constants or samplers yet.  Just basic loops with a uniform-specified index (something GL has had for a long time).  It's good to see indexed constants are possible in ES 3.0 (for indexed light shaders).  The workaround I have will suffice for controlling looping, but isn't as efficient, and I always worry about loop unrolling and shader limits.  It's sad that the bindless APIs haven't spread to non-Nvidia drivers.

Florian Bösch

unread,
Apr 20, 2014, 3:29:44 AM4/20/14
to webgl-d...@googlegroups.com
On Sunday, April 20, 2014 12:45:39 AM UTC+2, Kenneth Russell wrote:
As Jeff pointed out, section 12.30 "Dynamic Indexing" in the GLSL ES
3.00.4 specification lifts most of the restrictions in OpenGL ES 2.0
and therefore WebGL 1.0. However, and unfortunately, in OpenGL ES 3.0,
arrays of samplers can only be indexed with
constant-integral-expressions. I don't know the reason for this
restriction. Perhaps an OpenGL ES extension could be defined which
would lift it, and that could then be exposed in WebGL.

Only arrays of samplers? Because OpenGL ES 3.0 has array textures and 3d textures, and those don't need array indexing to function, and would be the preferred way to access a 3D structure of samplers. 

Kenneth Russell

unread,
Apr 20, 2014, 11:47:08 AM4/20/14
to webgl-d...@googlegroups.com
That's my understanding of the spec.
Reply all
Reply to author
Forward
0 new messages