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 2 12 LastLast
Results 1 to 10 of 13

Thread: Issue about accessing array element of uniform block (AMD glsl compiler)

  1. #1
    Junior Member Newbie
    Join Date
    Aug 2009
    Posts
    22

    Question Issue about accessing array element of uniform block (AMD glsl compiler)

    I have encountered an issue about accessing array element of uniform block, the follow code can demonstrate this issue:

    Code :
    struct SLightSource {
        vec3 color1;
        vec3 color2;
    };
     
    layout(std140) uniform LightSourcesBlock {
        SLightSource lightSources[32];
    };
     
    vec3 CalcLightColor(const in SLightSource lightSource)
    {
        return lightSource.color1 + lightSource.color2;
    }
     
    uniform int lightCount;
    out vec4 fragColor;
     
    void main()
    {
        vec3 lightColor = vec3(0, 0, 0);
        for (int i = 0; i < lightCount; i++)
            lightColor += CalcLightColor(lightSources[i]);
     
        fragColor = vec4(lightColor, 1);
    }

    The Above code is very simple but it is enough to demonstrate this issue. Suppose the array in uniform block has been initialized with uniform buffer object: lightSources[0].color1 = (0.25, 0.25, 0.25), lightSources[0].color2 = (0.25, 0.25, 0.25),lightSources[1].color1 = (0.25, 0.25, 0.25),lightSources[1].color2 = (0.25, 0.25, 0.25), and the uniform lightCount is set to 2;
    Run the program and the expected output color should be (1, 1, 1). In nVidia video card the output color is OK, but if I run this code in AMD video card the result will be (0.5, 0.5, 0.5), (I have an AMD Radeon HD 7770 card with Catalyst 13.1 driver)
    I seems that the uniform value of the second array element in the uniform block is zero when the program evalulate their value. I have checked that both lightSources[1].color1 and lightSources[1].color2 are active uniform after the program is linked.
    But if I change the light calcaultion code as follow the output color will be correct:

    Code :
    void main()
    {
        vec3 lightColor = vec3(0, 0, 0);
        lightColor += CalcLightColor(lightSources[0]);
        lightColor += CalcLightColor(lightSources[1]);
        fragColor = vec4(lightColor, 1);
    }

    It looks like that when I access array element by a constant number as its index every thing is fine, but if I use a variable as the array index some strange thing will happen. So is this a feature of GLSL language I have not fully understand or a bug in AMD GLSL compiler?

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,117
    How are you loading the structure? std140 says that that vec3 will be padded to a vec4. (http://www.opengl-redbook.com/appendices/AppL.pdf)

  3. #3
    Junior Member Newbie
    Join Date
    Aug 2009
    Posts
    22
    Quote Originally Posted by tonyo_au View Post
    How are you loading the structure? std140 says that that vec3 will be padded to a vec4. (http://www.opengl-redbook.com/appendices/AppL.pdf)
    I can assure that my uniform buffer layout is correct, since I have query the uniform offset by glGetActiveUniformsiv(), and the result coincides with the layout of my uniform buffer layout. And of course vec3 has a base alignment of 16 bytes, this is described in openGL specification, I obey the spec strictly :-)

  4. #4
    Junior Member Regular Contributor
    Join Date
    Nov 2012
    Location
    Bremen, Germany
    Posts
    167
    I do not know if this is really the issue, but take a look here:
    http://www.opengl.org/discussion_boa...th-GLSL-arrays

    On older (ATI)-Cards using non-constants as array-index resulted in a compile-time error. Maybe you have to use a
    #version xxx
    statement before you can use non-const indices (I do not have Access to newer ati-hardware right now so i cannot test this).

  5. #5
    Member Regular Contributor Nowhere-01's Avatar
    Join Date
    Feb 2011
    Location
    Novosibirsk
    Posts
    251
    in AMD ShaderAnalyzer, this shader doesn't even compile. for some reason it doesn't like you declaring uniform block of struct. i don't actually have experience with uniform blocks, so i couldn't fix it; but it does compile that way:

    Code :
    layout (std140) uniform LightSourcesBlock {
        vec3 color1[32];
        vec3 color2[32];
    };
     
    vec3 CalcLightColor(const in vec3 c1, const in vec3 c2) {
        return c1 + c2;
    }
     
    uniform int lightCount;
    out vec4 fragColor;
     
    void main() {
        vec3 lightColor = vec3(0, 0, 0);
        for (int i = 0; i < lightCount; i++) {
            lightColor += CalcLightColor(color1[i], color2[i]);
        }
        fragColor = vec4(lightColor, 1);
    }

    can you check if it produces correct result on AMD card? this is my obsessive fear with GLSL - AMD Compiler, especially with arrays. so i'm quite invested in making sure it's not a new AMD "feature".

  6. #6
    Junior Member Newbie
    Join Date
    Aug 2009
    Posts
    22
    Quote Originally Posted by hlewin View Post
    I do not know if this is really the issue, but take a look here:
    http://www.opengl.org/discussion_boa...th-GLSL-arrays

    On older (ATI)-Cards using non-constants as array-index resulted in a compile-time error. Maybe you have to use a
    #version xxx
    statement before you can use non-const indices (I do not have Access to newer ati-hardware right now so i cannot test this).
    In fact, I put a "#version 150" line in the shader since I use OpenGL 3.2 core profile (I fogot to mention this in my first post), the shader compile with no error, but the result is what I have described before. Do you know from which version of GLSL language non-constant array index is allowed ? thanks.

  7. #7
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,117
    According to http://www.opengl.org/wiki/GLSL_Type

    Arrays can be accessed with arbitrary numeric expressions. They do not have to be compile-time constants (though there are a few exceptions to this rule; for example, the very next section).

    They are valid from 4.00 for opaque types.
    Last edited by tonyo_au; 01-27-2013 at 05:45 PM.

  8. #8
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    Do you know from which version of GLSL language non-constant array index is allowed ?
    All of them. At least, for arrays of regular values. GLSL 1.10 allowed this.

    I'd guess that this is a driver bug. Try using vec4's instead of vec3's; it's best not to confuse AMD drivers...

    They are valid from 4.00 for opaque types.
    Point of order: as stated in "the very next section", they aren't. Only Dynamically Uniform Expressions can be used with opaque types.

    But that's irrelevant, since he isn't using an opaque type here.

  9. #9
    Junior Member Regular Contributor
    Join Date
    Nov 2012
    Location
    Bremen, Germany
    Posts
    167
    Do you know from which version of GLSL language non-constant array index is allowed ? thanks.
    All of them. At least, for arrays of regular values. GLSL 1.10 allowed this. I'd guess that this is a driver bug. Try using vec4's instead of vec3's; it's best not to confuse AMD drivers...
    That's true from reading the spec - yes. I've an old Laptop with a Radeon-mobility where I got the compile-time Errors. As I said I do not know for newer Cards. It was just a thought that the Compiler might treat sources different depending on what Version is requested. I'd try to specify the highest Version and test if it works and then decrease the version-number. Otherwise I would not really know how to handle this.
    On the old Laptop i used to roll out Loops by Hand to enable accessing the Array.
    #define LOOP(x) CallFunction(ArrayValue[x], AnOtherArray[x])
    LOOP(0); LOOP(1); LOOP(2)...
    Of course this is ridiculous so I would have expected that this behaviour is fixed for newer Cards/newer drivers.
    If you try out please post the results here as I'm quite interested in the results.

  10. #10
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,117
    Quote Originally Posted by Alfonse Reinheart View Post
    Point of order: as stated in "the very next section", they aren't. Only Dynamically Uniform Expressions can be used with opaque type
    I thought his index is Dynamically Uniform Expressions since lightCount is a Dynamically Uniform Expressions?

Posting Permissions

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