2
\$\begingroup\$

Ok guys, I think I have a very strange problem.

I have an old laptop, but its HD 6370M currently supports opengl 4.4, so i decided to learn how to use some new features of this platform, so after glVertexAttribFormat, glVertexAttribBinding and so on, I moved to shader storage buffer objects.

I thought they were useful for things like passing light data to shaders, so I tried to make a trivial example working.

the relevant pieces of code in my program are: C++ creation of buffer

    struct Values
    {
        float val;
    };

    void CreateBuffers()
    {
        glGenBuffers(1, &ssbo);
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);

        Values v;
        v.val = 0.3;

        glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Values), &v, GL_STATIC_DRAW);
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
    }

    void Render()
    {
        ...
        glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
        ...
    }

Then in the fragment shader: GLSL

    struct Values
    {
        float val;
    };

    layout(std430, binding = 0) buffer ssbo
    {
        Values vals[];
    };

And then in the main I could assign a random color to the output variable and I just see my geometry of that color, as expected:

    out vec4 out_color;
    void main()
    {
         out_color = vec4(0.4, 0.3, 0.6, 1); // Yeah, random
    }

Or if I output the value of the variable in the ssbo directly everything works just fine (I see a grayish color on my geometry)

    out vec4 out_color;
    void main()
    {
         out_color = vec4(vals[0].val);
    }

BUT, if I try to get the length of the array with

    vals.length();

in any kind of operation, like in a for loop or simply scale the output color by the length of the array, I get a completely white screen, even if the clear color is set to black, and no geometry is visible at all. It is important to say that this only happen if in the ssbo i put an array of structures.

I don't think that's relevant, but I'm using Windows 8.1 and MSVC compiler with VS13.

Thanks in advance.

EDIT: I want to say that no error is generated during runtime, the shaders compile successfully and the program is validated and linked

EDIT 2: Ok, now it seems that there is a linking error on the program where the ssbo is, but the infolog says nothing:

    Vertex shader(s) failed to link, fragment shader(s) failed to link.
    Vertex link error: INVALID_OPERATION.
    unexpected error.
    fragment link error: INVALID_OPERATION.
    unexpected error.

Driver bug?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I have the same issue, windows 8.1x64 R9290. The shader cannot read the length of a buffer. I got round this by creating another SSBO with containing the lengths of the Light array.

I don't need to do this on Nvidia or Intel chips. Another issue is that vec3 types didn't seem to work due to memory padding, so I manually pad all data as a vec4.

This somewhat 'works', I can access any struct in the light array, but I'm having issues with only being able to access the first element of that struct. So I can access DLights[0].ambient, and DLights[3].ambient; but not DLights[0].light_dir. Again, this isn't an issue on nvidia or intel.

Here is the rough gist of my shader, hope this helps.

struct directional_light {
  vec4 ambient;
  vec4 light_colour;
  vec4 light_dir; // Light_dir is a vec3, padded in a vec4
};

layout(std430, binding = 1) buffer DirectionalLights { directional_light DLights[]; };

//lightNumbers.x = Number of Dlights, lightNumbers.y = Number of Plights...
layout(std430, binding = 4) buffer LightStats { vec4 lightNumbers; };

...
void main(){
  ...
  // for (int i = 0; i < DLights.length() ; i++) {
  for (int i = 0; i < lightNumbers.x; i++) {
   colour += calculate_dir(DLights[i], position, normal, view_dir, tex_colour);
  }
}
\$\endgroup\$
1
  • \$\begingroup\$ Uhm, that's interesting. The fact that this driver bug happens also on a graphics core next GPU makes me sad... Oh and for the second buffer you could use a uniform block, and btw when there is only one variable (lightNumbers) memory padding shouldn't be an issue \$\endgroup\$
    – DI2edd
    Apr 17, 2015 at 16:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .