Estoy tratando de descubrir cuál es la mejor manera de generar una textura OpenGL usando un sombreador de cómputo. Hasta ahora, he leído que los objetos de búfer de píxeles son buenos para CPU sin bloqueo -> transferencias de GPU, y que los sombreadores de cómputo son capaces de leer y escribir búferes independientemente de cómo estén vinculados. Idealmente, me gustaría evitar tantas copias como sea posible. En otras palabras, me gustaría asignar un búfer en la GPU, escribir datos de textura comprimidos y luego usar ese búfer como un objeto de textura en un sombreador.
Actualmente, mi código se parece a esto:
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);
¿Es esto correcto? También leí en alguna parte sobre garantizar la sincronización. ¿Qué necesito agregar para asegurarme de que mi sombreador de cómputo complete la ejecución antes de copiar desde el objeto de búfer?
fuente
Respuestas:
Después de investigar esto por un tiempo, descubrí un par de cosas:
No puede evitar una memoria : no puede escribir directamente en el almacenamiento de texturas asignado para una textura comprimida utilizando solo llamadas de API OpenGL. Esto significa que no puede evitar la llamada
glCompressedTexImage2D
con un PBO vinculado. Dicho esto, es posible que pueda usar una textura RGBA de 16 bits y un tipo de imagen GLSL en su sombreador de cómputo.Debe sincronizar la memoria : para asegurarse de que su sombreador de cómputo termine de escribir en su búfer de almacenamiento, debe asegurarse de que todas las lecturas y escrituras terminen. Esto se hace llamando
glMemoryBarrier
aGL_SHADER_STORAGE_BARRIER_BIT
.El código completo de algo que se escribe en un búfer para ser usado como una textura comprimida se ve así:
fuente
GL_SHADER_STORAGE_BARRIER_BIT
Barrera equivocada. La barrera que proporciona establece cómo utilizará la memoria. No cómo le escribió el sombreador. Estás haciendo una transferencia de píxeles, por lo que debes usarloGL_TEXTURE_UPDATE_BARRIER_BIT
GL_TEXTURE_UPDATE_BARRIER_BIT
se utiliza al sincronizar llamadasglTexImage
y no tiene nada que ver con la memoria utilizada en las memorias intermedias de almacenamiento. Creo que quisiste decirGL_PIXEL_BUFFER_BARRIER_BIT
?