Асинхронная блокировка потоков glTexSubImage2D и OGL - PullRequest
1 голос
/ 31 июля 2011

Я работаю над приложением GPGPU, которое передает данные между процессором и процессором, используя PBO. Одно из требований моего приложения состоит в том, что поток рендеринга OpenGL должен блокировать как можно меньше, а обработка должна иметь как можно меньшую задержку.

У меня вопрос: нужно ли добавить задержку между вызовом glTexSubImage2D (который запускает преобразование с хоста на устройство) и фактическим использованием / рендерингом с текстурой? Насколько большой должна быть такая задержка для текстуры, например размер 1024x1024?

for(auto texture: textures)
{
    glBindTexture(GL_TEXTURE_2D, texture.id());
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, ...);
    glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, ..., NULL, GL_STREAM_DRAW);
    void* mem = glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
    copy(mem, data);
    glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
    glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, ..., NULL);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
}

do_other_cpu_stuff_while_data_is_transferring(); // Is this needed to avoid blocking calls while rendering? If so, what strategy can I use to estimate the minimum amount of time needed to transfer the data.

for(auto texture: textures)
{
    render(texture);
}

Ответы [ 2 ]

3 голосов
/ 31 июля 2011

Я бы сказал, что наибольшая задержка будет при вызове copy () и / или glUnmapBuffer (), но это будет зависеть от многих вещей (в основном от вашего оборудования), что лучше всего делать одну передачу в начало программы и измерить их. Для определения времени вы должны использовать функцию glFinish () с таймером высокого разрешения (например, QuerPerformanceCounter).

1 голос
/ 01 августа 2011

Поскольку это структурировано, оно, скорее всего, заблокируется в glTexSubImage (хотя в конечном итоге это зависит от реализации, теоретически реализация может отложить это).Скорее всего, у вас будет гораздо меньше остановок, если вы сначала загрузите пару буферов, а затем будете вызывать glTexSubImage для каждого из них в порядке их определения / загрузки.

Вызов do_other_cpu_stuff, скорее всего, не поможетмного, потому что он уже блокируется ранее.

Если у вас есть доступная функциональность ARB_copy_buffer, вы можете избежать дальнейшего зависания, сначала определив некоторые данные буфера во временном буфере, а затем указав OpenGL сделать копию буфера в буферГрафический процессор.
Интуитивно понятно, что это не должно быть ни быстрее (скорее, медленнее), но по какой-то причине это вне меня, на самом деле быстрее .

...