Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 7 of 7

Thread: GLSL loop problem on Radeon HD cards?

  1. #1
    Intern Contributor
    Join Date
    Nov 2010
    Posts
    85

    GLSL loop problem on Radeon HD cards?

    I have a problem in my shaders on an ATI Radeon HD 5450 card (but I have reports from customers on other Radeon HD cards too, as well as one nVidia GeForce GT 330M).

    It works fine on an ATI FirePro v3750 (and other cards) though.

    It seems due to the loops I do in my code, because I tried to unroll them and it works fine.

    I there some kind of limitation on loops with these cards?

    My shader computes phong illumination for 4 lights, doing a loop on them.

    Here's an extract of the meaningful parts involving the loops:

    Code :
    uniform bvec4 LightsEnabled; // holds the booleans telling which lights are enabled
     
    void main(void)
    {
        vec4 finalColor;
     
        vec4 DiffuseColor[4];
        vec4 SpecularColor[4];
     
       for (int i = 0; i < 4; i++)
       {
            DiffuseColor[i] = vec4(0);
            SpecularColor[i] = vec4(0);
     
            if (LightsEnabled[i])
            {
                DirectionalLight(i, normal, amb, DiffuseColor[i], SpecularColor[i]);
     
                DiffuseColor[i]  *=  materialDiffuse;
     
                finalColor += DiffuseColor[i];
     
            }
     
       }
     
       gl_FragColor = finalColor;

  2. #2
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    5,932

    Re: GLSL loop problem on Radeon HD cards?

    Your problem is likely here:

    Code :
    if (LightsEnabled[i])

    The spec says that this is possible, but it's one of those outside cases that I would look dimly at. Just use a `bool[4]` array instead of a `bvec4`.

    Also, this is a poorly written shader. It can be rewritten as this:

    Code :
       for (int i = 0; i < 4; i++)
       {
         vec4 diffuseLightIntensity;
         vec4 specularLightIntensity
     
         if (LightsEnabled[i])
         {
            DirectionalLight(i, normal, amb, diffuseLightIntensity, specularLightIntensity);
     
            finalColor += diffuseLightIntensity * materialDiffuse;
         }
       }

    No need for arrays of those values; just overwrite the old ones. Nor is there a need to initialize them with 0; `DirectionalLight` should be outputting to those variables, so it should initialize them.

  3. #3
    Intern Contributor
    Join Date
    Nov 2010
    Posts
    85

    Re: GLSL loop problem on Radeon HD cards?

    Thank you Alfonse,

    but why is the use of bool[4] different from using a bvec4?

  4. #4
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    5,932

    Re: GLSL loop problem on Radeon HD cards?

    The difference is that most people do not access a vector using [] with non-compile-time values. This means that, while GLSL says that this should be possible, drivers don't see this case often. So there can be bugs in it, much like the one you ran into.

    The majority of uses of arrays do use them with non-compile time values, in looping structures and such. Your use case is common for arrays, so drivers will have seen that case fairly often. And therefore, they're less likely to be broken.

  5. #5
    Intern Contributor
    Join Date
    Nov 2010
    Posts
    85

    Re: GLSL loop problem on Radeon HD cards?

    Hi Alfonse,

    I have another problematic piece of code that works on some cards but not on others:

    Code :
        const int NumberOfSplits = 4;
        varying vec4  ShadowCoord[NumberOfSplits]; 
        uniform float SplitDepths[NumberOfSplits];
     
    ...
     
        vec4 coord;
     
        for (int i = 0; i < NumberOfSplits; i++)
        {                
            if (vertexDepth > SplitDepths[i])
            {
                coord = ShadowCoord[i];
                break;
            }
        }

    if I unroll it like this it works in all cards (or at least in those that I tested):

    Code :
        vec4 coord;
     
        for (int i = 0; i < NumberOfSplits; i++)
        {                
            if (vertexDepth > SplitDepths[i])
            {
                if (i==0)         
                    coord = ShadowCoord[0];
                else if (i==1)
                    coord = ShadowCoord[1];
                else if (i==2)
                    coord = ShadowCoord[2];
                else
                    coord = ShadowCoord[3];
     
                break;
            }
     
        }

    Am I doing something wrong in the first case, with
    Code :
                coord = ShadowCoord[i];
    ?

    Thanks

  6. #6
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    5,932

    Re: GLSL loop problem on Radeon HD cards?

    What do you expect me or anyone else to do about it? Or anyone else? It's a driver bug.

    You have two alternatives:

    1: Live with these bugs and continue to create workarounds for them until they get fixed.

    2: Stop using varying arrays and other things.

    These are your options. If you want your code to work everywhere without workarounds, then you're going to have to stop doing these unusual things like this. Yeah, it's not fair, it should work, but that's life.

  7. #7
    Intern Contributor
    Join Date
    Nov 2010
    Posts
    85

    Re: GLSL loop problem on Radeon HD cards?

    I didn't know using a varying array was an unusual thing.

    Where can I find a list of all these unusual things, so I can start writing better shaders code?

    Thanks for your time.

Posting Permissions

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