Нужен ли мне барьер памяти между инициализацией хранилища SSBO и его заполнением? - PullRequest
1 голос
/ 10 июня 2019

У меня есть код, похожий на этот:

uint ssboId;
glGenBuffers(1, &ssboId);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssboId);

//initialize
glBufferData(GL_SHADER_STORAGE_BUFFER, size, 0, GL_STATIC_DRAW);


// memory barrier here?
// glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);


//start writes
glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset1, sourceSize1, data1);
glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset2, sourceSize2, data2);
...

// Ensure changes are applied before shader grabs it.
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);


Нужно ли раскомментировать вызов glMemoryBarrier, который находится между glBufferData и glBufferSubData?Если материал SSBO непоследователен, не может ли быть так, что glBufferSubData проходит до glBufferData и, таким образом, вылетает?

Мое приложение работает, но я не уверен, работает ли оно просто по счастливой случайности.

1 Ответ

3 голосов
/ 10 июня 2019

Оба вызова на glMemoryBarrier не обязательны. Почти все функции OpenGL (включая glBufferData и glBufferSubData) соответствуют традиционной модели памяти OpenGL, где синхронизация гарантируется автоматически.

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

//Init SSBO
glBufferData(...);
glBufferSubData(...);

//No sync needed here

glDispatchCompute(...); //Shader which writes to the SSBO

//Sync here to make writes visible
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);

//Read back SSBO memory
glMapBuffer(...);
...
...