Я пытаюсь выяснить, как лучше всего создать текстуру OpenGL с помощью вычислительного шейдера. До сих пор я читал, что объекты пиксельного буфера хороши для неблокирующей передачи CPU -> GPU, и что вычислительные шейдеры способны читать и записывать буферы независимо от того, как они связаны. В идеале я хотел бы избежать как можно большего количества копий. Другими словами, я хотел бы выделить буфер на GPU, записать сжатые данные текстуры в него, а затем использовать этот буфер в качестве объекта текстуры в шейдере.
В настоящее время мой код выглядит примерно так:
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, tex_size_in_bytes, 0, 0);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
// Bind buffer to resource in compute shader
// execute compute shader
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
glCompressedTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, tex_size_in_bytes, 0);
Это правильно? Я тоже где-то читал о гарантии синхронизации. Что мне нужно добавить, чтобы убедиться, что мой вычислительный шейдер завершает выполнение до копирования из объекта буфера?
источник
Ответы:
Посмотрев на это некоторое время, я обнаружил пару вещей:
Вы не можете избежать использования memcpy : вы не можете писать напрямую в хранилище текстур, выделенное для сжатой текстуры, используя только вызовы API OpenGL. Это означает, что вы не можете избежать вызова
glCompressedTexImage2D
с привязанным PBO. При этом вы можете использовать 16-битную текстуру RGBA и тип изображения GLSL в своем вычислительном шейдере.Вам необходимо синхронизировать память : чтобы убедиться, что ваш вычислительный шейдер завершает запись в буфер хранения, вы должны убедиться, что все операции чтения и записи в него завершены. Это делается по телефону
glMemoryBarrier
сGL_SHADER_STORAGE_BARRIER_BIT
.Полный код для чего-то, что записывает в буфер для использования в качестве сжатой текстуры, выглядит следующим образом:
источник
GL_SHADER_STORAGE_BARRIER_BIT
Неправильный барьер. Предоставляемый вами барьер указывает, как вы будете использовать память. Не так, как шейдер написал в него. Вы делаете передачу пикселей, поэтому вам нужно использоватьGL_TEXTURE_UPDATE_BARRIER_BIT
GL_TEXTURE_UPDATE_BARRIER_BIT
используется при синхронизации вызововglTexImage
и не имеет ничего общего с памятью, используемой в буферах хранения. Я думаю ты имел ввидуGL_PIXEL_BUFFER_BARRIER_BIT
?