如何查询 SSBO 结构的对齐/步幅?

Mr.*_*ith 3 opengl shader glsl opengl-4 shader-storage-buffer

我不确定哪种结构布局最适合我的应用程序:sharedpackedstd140std430。我并不是要对每一个进行解释,这些信息很容易找到,只是很难弄清楚每个对供应商兼容性/性能的影响。如果shared是默认值,我怀疑这是一个很好的起点。

据我所知,我必须在使用sharedor时查询对齐/偏移量packed,因为它是特定于实现的。

用于查询它的 API 是什么?glGetShaderiv在绑定计算着色器时,我是否传递了一些参数,让我找出对齐方式?

Rab*_*d76 5

glGetProgramInterface与参数GL_SHADER_STORAGE_BLOCK一起使用可获取 Shader Storage Buffer Objects 的数量和最大名称长度。
缓冲区变量的最大名称长度可以从程序界面获得GL_BUFFER_VARIABLE

GLuint prog_obj; // shader program object
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)

可以通过以下方式获取 SSBO 的名称glGetProgramResourceName和资源索引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());

    // [...]
}
Run Code Online (Sandbox Code Playgroud)

可以通过 检索着色器存储块的数据glGetProgramResource。另请参阅程序自省

从程序接口和GL_SHADER_STORAGE_BLOCK着色器存储块资源中获取缓冲区变量的数量及其索引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());

    // [...]
}
Run Code Online (Sandbox Code Playgroud)

从程序接口GL_BUFFER_VARIABLE和资源索引中获取缓冲区变量的偏移量,以基本机器为单位,相对于缓冲区的基址及其名称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();
    }

    // [...]
}
Run Code Online (Sandbox Code Playgroud)

也可以看看 ARB_shader_storage_buffer_object