Как мне запросить выравнивание / шаг для структуры SSBO?

Я не уверен, какой макет структуры больше всего подходит для моего приложения: shared, _2 _, _ 3_, std430. Я не прошу объяснений по каждому из них, эту информацию легко найти, просто трудно понять, какое влияние каждый из них окажет на совместимость / производительность поставщика. Если по умолчанию используется shared, я подозреваю, что это хорошая отправная точка.

Из того, что я могу собрать, мне нужно запросить выравнивание / смещения при использовании shared или packed, потому что это зависит от реализации.

Для чего нужен API для запросов? Есть ли какой-то параметр, который я передаю в glGetShaderiv, пока вычислительный шейдер привязан, который позволяет мне выяснить выравнивания?


person Mr. Smith    schedule 09.06.2019    source источник


Ответы (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.

person Rabbid76    schedule 09.06.2019