Синхронизация последовательных вызовов OpenGL Compute Shader

12

У меня есть пара вычислительных шейдеров, которые должны быть выполнены в определенном порядке и чьи выходные данные зависят от предыдущих входных данных. В идеале мне никогда не понадобится копировать буфер на стороне клиента и выполнять всю мою работу на GPU.

Рассмотрим У меня есть два вычислительных шейдеров скомпилированы и связаны , как program_oneи program_two. Предположим, у меня также есть, GL_SHADER_STORAGE_BUFFERкоторый содержит данные, которые записаны program_oneи прочитаны program_two. Могу ли я просто сделать следующее:

glUseProgram(program_one);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffer);
glDispatchCompute(16, 16, 1);

glUseProgram(program_two);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffer);
glDispatchCompute(16, 16, 1);

Гарантируется ли, что все вызовы первого вычислительного шейдера завершатся раньше, чем вызовы второго (чтобы избежать гонок данных между чтением и записью buffer)? Если нет, как мне их синхронизировать?

Mokosha
источник

Ответы:

12

Нет, это не гарантируется, поскольку спецификация OpenGL позволяет двум вычислительным шейдерам работать одновременно или даже в разном порядке.

Вы должны позвонить glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT)до второго, glDispatchComputeчтобы обеспечить видимость записи с program_one.


Из вики-статьи OpenGL.org о модели памяти :

[...] вызовы между этапами могут выполняться в любом порядке. Это включает вызовы, запускаемые различными командами рендеринга. Хотя, вероятно, маловероятно, что два вершинных шейдера из разных операций рендеринга могли работать одновременно, это также возможно, поэтому OpenGL не дает никаких гарантий .

Из вики-статьи Opengl.org о буфере хранения шейдеров :

SSBO для чтения и записи использует несогласованный доступ к памяти, поэтому им необходимы соответствующие барьеры, так же как и операции Image Load Store.

Wumpf
источник