CrazySage
@CrazySage
C++ developer

Какие существуют ограничения на размер GL_SHADER_STORAGE_BUFFER?

Пишу трассировку лучей на OpenGL с использованием вычислительных шейдеров, для передачи данных использую буферы.

Когда размер выходного буфера (состоит из vec2, размер соответственно количество лучей*количество треугольников) переваливает примерно за 30Мб попытка сделать маппинг буфера в память приложения стабильно и воспроизводимо возвращает NULL, равно как и попытка примапить только часть буфера.

В документации я не нашёл информации о ограничении на размеры GL_SHADER_STORAGE_BUFFER'ов, может ли причина быть в чём-то ещё кроме слишком большого размера и можно ли как-то это обойти, кроме как многократным вызовом шейдера с меньшим количеством входных данных?

Объявление данных в самом шейдере:

#version 440
layout(std430, binding=0) buffer rays{
    vec4 r[];
};
layout(std430, binding=1) buffer faces{
    vec4 f[];
};
layout(std430, binding=2) buffer outputs{
    vec2 o[];
};
uniform int face_count;
uniform vec4 origin;


Код программы (используются обёртки из Qt5)

QOpenGLBuffer ray_buffer;
QOpenGLBuffer face_buffer;
QOpenGLBuffer output_buffer;

QVector<QVector2D> output;

output.resize(rays[r].size()*faces.size());

if(!ray_buffer.create()) { /*...*/ }
if(!ray_buffer.bind()) { /*...*/ }
ray_buffer.allocate(rays.data(), rays.size()*sizeof(QVector4D));

if(!face_buffer.create()) { /*...*/ }
if(!face_buffer.bind()) { /*...*/ }
face_buffer.allocate(faces.data(), faces.size()*sizeof(QVector4D));

if(!output_buffer.create()) { /*...*/ }
if(!output_buffer.bind()) { /*...*/ }

output_buffer.allocate(output.size()*sizeof(QVector2D));

ogl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ray_buffer.bufferId());
ogl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, face_buffer.bufferId());
ogl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, output_buffer.bufferId());

int face_count = faces.size();

compute.setUniformValue("face_count", face_count);
compute.setUniformValue("origin", pos);

ogl->glDispatchCompute(rays.size()/256, faces.size(), 1);

ray_buffer.destroy();
face_buffer.destroy();
QVector2D* data = (QVector2D*)output_buffer.map(QOpenGLBuffer::ReadOnly);
  • Вопрос задан
  • 177 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы