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 10 of 13

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

Hybrid View

  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
    149
    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.

Posting Permissions

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