Ich versuche herauszufinden, wie man am besten eine OpenGL-Textur mit einem Compute-Shader generiert. Bisher habe ich gelesen, dass Pixelpufferobjekte für nicht blockierende CPU-> GPU-Übertragungen geeignet sind und dass Compute-Shader Puffer lesen und schreiben können, unabhängig davon, wie sie gebunden sind. Im Idealfall möchte ich so viele Kopien wie möglich vermeiden. Mit anderen Worten, ich möchte einen Puffer auf der GPU zuweisen, komprimierte Texturdaten darauf schreiben und diesen Puffer dann als Texturobjekt in einem Shader verwenden.
Derzeit sieht mein Code ungefähr so aus:
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);
Ist das richtig? Ich habe auch irgendwo darüber gelesen, wie man Synchronisation garantiert. Was muss ich hinzufügen, um sicherzustellen, dass mein Compute-Shader die Ausführung vor dem Kopieren aus dem Pufferobjekt abschließt?
quelle
Antworten:
Nachdem ich mich eine Weile damit befasst hatte, fand ich ein paar Dinge heraus:
Sie können ein Memcpy nicht vermeiden : Sie können nicht direkt in den Texturspeicher schreiben, der einer komprimierten Textur zugewiesen ist, indem Sie nur OpenGL-API-Aufrufe verwenden. Dies bedeutet, dass Sie den Anruf
glCompressedTexImage2D
mit einem gebundenen PBO nicht vermeiden können . Abgesehen davon können Sie möglicherweise eine 16-Bit-RGBA-Textur und einen GLSL-Bildtyp in Ihrem Compute-Shader verwenden.Sie müssen den Speicher synchronisieren : Um sicherzustellen, dass Ihr Compute-Shader das Schreiben in Ihren Speicherpuffer beendet, müssen Sie sicherstellen, dass alle Lese- und Schreibvorgänge abgeschlossen sind. Dies geschieht durch einen Anruf
glMemoryBarrier
mitGL_SHADER_STORAGE_BARRIER_BIT
.Der vollständige Code für etwas, das in einen Puffer geschrieben wird, um als komprimierte Textur verwendet zu werden, sieht folgendermaßen aus:
quelle
GL_SHADER_STORAGE_BARRIER_BIT
Falsche Barriere. Die Barriere Sie bieten angibt , wie Sie verwenden den Speicher. Nicht wie der Shader darauf geschrieben hat. Sie machen eine Pixelübertragung, also müssen Sie verwendenGL_TEXTURE_UPDATE_BARRIER_BIT
GL_TEXTURE_UPDATE_BARRIER_BIT
verwendet, wenn Anrufe zu synchronisierenglTexImage
, und hat nichts mit dem Speicher in Speicherpuffern verwendet zu tun. Ich denke du meintestGL_PIXEL_BUFFER_BARRIER_BIT
?