Как я могу запросить выравнивание / шаг для структуры SSBO?
Я не уверен, какая структура структуры лучше всего подходит для моего приложения: shared
, packed
,std140
, std430
, Я не прошу объяснения каждому из них, эту информацию легко найти, просто трудно понять, какое влияние каждый из них окажет на совместимость / производительность поставщика. Если shared
по умолчанию, я подозреваю, что это хорошая отправная точка.
Из того, что я могу собрать, я должен запросить выравнивание / смещения при использовании shared
или же packed
потому что это зависит от реализации.
Для чего нужен API? Есть ли какой-то параметр, который я передаю glGetShaderiv
в то время как вычислительный шейдер связан, это позволяет мне выяснить выравнивания?
1 ответ
Использование glGetProgramInterface
с параметром GL_SHADER_STORAGE_BLOCK
чтобы получить количество объектов буфера хранилища шейдеров и максимальную длину имени.
Максимальную длину имени буферных переменных можно получить из интерфейса программы. 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
и индекс ресурса по 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
, Смотрите также Программа самоанализа.
Получить количество буферных переменных и их индексов из интерфейса программы и 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[]
:
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();
}
// [...]
}
Смотрите также ARB_shader_storage_buffer_object