openglglslshaderopengl-4shader-storage-buffer

How do I query the alignment/stride for an SSBO struct?


I'm not sure which structure layout is most suited for my application: shared, packed,std140, std430. I'm not asking for an explanation of each, that information is easy to find, it's just hard to figure out the impact each will have on vendor compatibility/performance. If shared is the default, I'm suspecting that's a good starting point.

From what I can gather, I have to query the alignment/offsets when using shared or packed, because it's implementation specific.

What's the API for for querying it? Is there some parameter I pass to glGetShaderiv while the compute shader is bound, that lets me figure out the alignments?


Solution

  • Use glGetProgramInterface with the parameter GL_SHADER_STORAGE_BLOCK to get the number of the Shader Storage Buffer Objects and the maximum name length.
    The maximum name length of the buffer variables can be get from the program interface GL_BUFFER_VARIABLE:

    GLuint prog_obj; // shader program object
    
    GLint no_of, ssbo_max_len, var_max_len;
    glGetProgramInterfaceiv(prog_obj, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &no_of);
    glGetProgramInterfaceiv(prog_obj, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, &ssbo_max_len);
    glGetProgramInterfaceiv(prog_obj, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, &var_max_len);
    

    The name of the SSBO can be get by glGetProgramResourceName and a resource index by glGetProgramResourceIndex:

    std::vector< GLchar >name( max_len );
    for( int i_resource = 0; i_resource < no_of; i_resource++ ) {
    
        // get name of the shader storage block
        GLsizei strLength;
        glGetProgramResourceName(
            prog_obj, GL_SHADER_STORAGE_BLOCK, i_resource, ssbo_max_len, &strLength, name.data());
    
        // get resource index of the shader storage block
        GLint resInx = glGetProgramResourceIndex(prog_obj, GL_SHADER_STORAGE_BLOCK, name.data());
    
        // [...]
    }
    

    Data of the shader storage block can be retrieved by glGetProgramResource. See also Program Introspection.

    Get the number of of buffer variables and its indices from program interface and GL_SHADER_STORAGE_BLOCK and the shader storage block resource resInx:

    for( int i_resource = 0; i_resource < no_of; i_resource++ ) {
    
        // [...]
    
        GLint resInx = ...
    
        // get number of the buffer variables in the shader storage block
        GLenum prop = GL_NUM_ACTIVE_VARIABLES;
        GLint num_var;
        glGetProgramResourceiv(
            prog_obj, GL_SHADER_STORAGE_BLOCK, resInx, 1, &prop,
            1, nullptr, &num_var);
    
        // get resource indices of the buffer variables
        std::vector<GLint> vars(num_var);
        prop = GL_ACTIVE_VARIABLES;
        glGetProgramResourceiv(
            prog_obj, GL_SHADER_STORAGE_BLOCK, resInx,
            1, &prop, (GLsizei)vars.size(), nullptr, vars.data());
    
        // [...]
    }
    

    Get the offsets of the buffer variables, in basic machine units, relative to the base of buffer and its names from the program interface GL_BUFFER_VARIABLE and the resource indices vars[]:

    for( int i_resource = 0; i_resource < no_of; i_resource++ ) {
    
        // [...]
    
        std::vector<GLint> offsets(num_var);
        std::vector<std::string> var_names(num_var);
        for (GLint i = 0; i < num_var; i++) {
    
            // get offset of buffer variable relative to SSBO
            GLenum prop = GL_OFFSET;
            glGetProgramResourceiv(
                prog_obj, GL_BUFFER_VARIABLE, vars[i],
                1, &prop, (GLsizei)offsets.size(), nullptr, &offsets[i]);
    
            // get name of buffer variable
            std::vector<GLchar>var_name(var_max_len);
            GLsizei strLength;
            glGetProgramResourceName(
                prog_obj, GL_BUFFER_VARIABLE, vars[i], 
                var_max_len, &strLength, var_name.data());
            var_names[i] = var_name.data();
        }
    
        // [...]
    }
    

    See also ARB_shader_storage_buffer_object