Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 3 123 LastLast
Results 1 to 10 of 28

Thread: unbound sampler declaration andd GLSL shader code

  1. #1
    Junior Member Regular Contributor
    Join Date
    Jul 2010
    Posts
    132

    unbound sampler declaration andd GLSL shader code

    Hi,

    I have the following code:

    Code :
    uniform int isBound;
    uniform usampler2D myImage;
     
    if (isBound == 1)
        do something with myImage, calls texelFetch;
    else
        do something without using myImage;
    Is this allowed to leave sampler uniforms effectively not bound to anything, at certain times?
    Sorry if this question seems obvious but I have a bug whereby a single texelFetch, not executed in my code (because isBound is 0), causes my shader to freeze. Although never executed, commenting out the texelFetch call indeed removes the issue. I suspect either a GLSL compiler issue as my shader code is very complex (> 2000 lines), or a driver issue. Even more likely, a problem with my code

    Cheers,
    Fred
    Last edited by fred_em; 06-25-2013 at 07:59 AM. Reason: usampler2D, not uimage2D

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Apr 2010
    Location
    Germany
    Posts
    1,129
    The cause is that under certain conditions, all branches of a conditional statement are evaluated, no matter what. In any case, don't program stuff that may lead to undefined behavior.

  3. #3
    Junior Member Regular Contributor
    Join Date
    Jul 2010
    Posts
    132
    My isBound uniform value is 0 in all situations (it's pretty much a constant), and the problem remains. That's what I don't understand, as I know the GPU just cannot execute the code I don't want it to execute.

  4. #4
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    498
    Quote Originally Posted by thokra View Post
    The cause is that under certain conditions, all branches of a conditional statement are evaluated, no matter what. In any case, don't program stuff that may lead to undefined behavior.
    In GLSL 4.x, expressions which only involve constants and uniform variables are "dynamically uniform". Using a dynamically-uniform expression as the condition in an "if" statement should ensure that the other branch is never executed. Earlier versions don't require this; so both branches can be executed (unless the condition only involves constants). If you need to rely upon the 4.x behaviour, use "#version 400" or above.

  5. #5
    Junior Member Regular Contributor
    Join Date
    Jul 2010
    Posts
    132
    Quote Originally Posted by GClements View Post
    In GLSL 4.x, expressions which only involve constants and uniform variables are "dynamically uniform". Using a dynamically-uniform expression as the condition in an "if" statement should ensure that the other branch is never executed. Earlier versions don't require this; so both branches can be executed (unless the condition only involves constants). If you need to rely upon the 4.x behaviour, use "#version 400" or above.
    The GLSL version I'm using is #version 420 compatibility
    This problem really is driving nuts.
    The offending code is in a fragment shader. If I do:

    if (gl_FragCoord.x > 10000)
    texelFetch();
    else
    do something else;

    the problem occurs. Although there is absolutely no chance texelFetch() gets executed - if I comment it out, the problem goes away. I can't find out why there is a problem all of a sudden when I add a texelFetch call ...that is never executed!

  6. #6
    Senior Member OpenGL Pro
    Join Date
    Apr 2010
    Location
    Germany
    Posts
    1,129
    Quote Originally Posted by GClements
    In GLSL 4.x, expressions which only involve constants and uniform variables are "dynamically uniform". Using a dynamically-uniform expression as the condition in an "if" statement should ensure that the other branch is never executed. Earlier versions don't require this; so both branches can be executed (unless the condition only involves constants). If you need to rely upon the 4.x behaviour, use "#version 400" or above.
    My bad. Wasn't thinking. In the above case, I guess there's just no way control flow could take another path.

    EDIT:
    Quote Originally Posted by fred_em
    if (gl_FragCoord.x > 10000)
    texelFetch();
    else
    do something else;
    I'd say that this is actually non-uniform control flow - unless the implementation can cleverly deduce that gl_FragCoord.x can never be greater than 10000. Does the problem persist if you use a constant expression?

    Code :
    if (false)
      texelFetch();
    else
      do something else;
    Last edited by thokra; 06-25-2013 at 08:47 AM.

  7. #7
    Junior Member Regular Contributor
    Join Date
    Jul 2010
    Posts
    132
    Quote Originally Posted by thokra View Post
    Does the problem persist if you use a constant expression?
    with if (false), the problem disappears, but I suspect it's because the GLSL compiler discards the compilation of the whole (false) condition block. (GLSL compilers are pretty good at this).

    With if (isBound) the problem remains.

    isBound is a vec3 in my code, eg.

    uniform vec3 isBound;

    I use isBound.r which is 0.0 in all cases. At runtime, I do if (isBound.r == 1.0), which is never true.

    GClements, is what you said valid for vec3 as well? Just a thought.

  8. #8
    Member Regular Contributor malexander's Avatar
    Join Date
    Aug 2009
    Location
    Ontario
    Posts
    327
    I found with the AMD drivers, if I left a samplerBuffer unbound it would crash even if I didn't sample from it. I ended up generating 3 dummy TBOs (float, int, uint) and binding those to the samplerBuffers were "not active". Perhaps you could do something similar with a dummy unsigned 2D texture.

  9. #9
    Junior Member Regular Contributor
    Join Date
    Jul 2010
    Posts
    132
    I'm using an nvidia GTS 450 card (drivers 311.06) but I suspect it could be the kind of problem you mention.

    It's tricky in my code to have a buffer bound at all times as the isBound==true fragment execution is acting as an add-on. The original drawing code in the fragment shader doesn't want to bother with the image2D, as it is not affected by it.

  10. #10
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    498
    Quote Originally Posted by fred_em View Post
    GClements, is what you said valid for vec3 as well? Just a thought.
    The type doesn't matter.

    Because GLSL assumes (and GPUs implement) a SIMD architecture, a conditional is typically executed by executing both branches but ignoring state changes in whichever branch wasn't selected by the condition. But if a non-selected branch results in an error, it can still effect the overall execution of the shader.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •