如何在 alignment/stride 中查询 SSBO 结构?
How do I query the alignment/stride for an SSBO struct?
我不确定哪种结构布局最适合我的应用程序:shared
、packed
、std140
、std430
。我并不是要对每个信息进行解释,这些信息很容易找到,只是很难弄清楚每个信息对供应商的影响 compatibility/performance。如果 shared
是默认值,我怀疑这是一个很好的起点。
据我所知,在使用 shared
或 packed
时,我必须查询 alignment/offsets,因为它是特定于实现的。
查询的API是什么?在绑定计算着色器时,是否有一些参数传递给 glGetShaderiv
,让我计算出对齐方式?
使用glGetProgramInterface
和参数GL_SHADER_STORAGE_BLOCK
得到
Shader Storage Buffer Objects 和最大名称长度。
缓冲区变量的最大名称长度可以从程序接口获取 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);
SSBO的名称可以通过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());
// [...]
}
着色器存储块的数据可以通过glGetProgramResource
. See also Program Introspection检索。
从程序接口和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());
// [...]
}
从程序接口GL_BUFFER_VARIABLE
和资源索引vars[]
:[=31=获取缓冲区变量的偏移量,以基本机器单位表示,相对于缓冲区及其名称的基数]
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();
}
// [...]
}
我不确定哪种结构布局最适合我的应用程序:shared
、packed
、std140
、std430
。我并不是要对每个信息进行解释,这些信息很容易找到,只是很难弄清楚每个信息对供应商的影响 compatibility/performance。如果 shared
是默认值,我怀疑这是一个很好的起点。
据我所知,在使用 shared
或 packed
时,我必须查询 alignment/offsets,因为它是特定于实现的。
查询的API是什么?在绑定计算着色器时,是否有一些参数传递给 glGetShaderiv
,让我计算出对齐方式?
使用glGetProgramInterface
和参数GL_SHADER_STORAGE_BLOCK
得到
Shader Storage Buffer Objects 和最大名称长度。
缓冲区变量的最大名称长度可以从程序接口获取 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);
SSBO的名称可以通过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());
// [...]
}
着色器存储块的数据可以通过glGetProgramResource
. See also Program Introspection检索。
从程序接口和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());
// [...]
}
从程序接口GL_BUFFER_VARIABLE
和资源索引vars[]
:[=31=获取缓冲区变量的偏移量,以基本机器单位表示,相对于缓冲区及其名称的基数]
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();
}
// [...]
}