J'essaie de comprendre quelle est la meilleure façon de générer une texture OpenGL à l'aide d'un shader de calcul. Jusqu'à présent, j'ai lu que les objets tampons en pixels sont bons pour les transferts CPU non bloquants -> GPU, et que les shaders de calcul sont capables de lire et d'écrire des tampons quelle que soit la façon dont ils sont liés. Idéalement, j'aimerais éviter autant de copies que possible. En d'autres termes, j'aimerais allouer un tampon sur le GPU, y écrire des données de texture compressées, puis utiliser ce tampon comme objet de texture dans un shader.
Actuellement, mon code ressemble à ceci:
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);
Est-ce correct? J'ai lu quelque part sur la garantie de la synchronisation aussi. Que dois-je ajouter pour m'assurer que mon shader de calcul termine l'exécution avant de copier à partir de l'objet tampon?
la source
Réponses:
Après avoir examiné cela pendant un certain temps, j'ai découvert deux ou trois choses:
Vous ne pouvez pas éviter un memcpy : vous ne pouvez pas écrire directement dans le stockage de texture alloué pour une texture compressée en utilisant uniquement les appels API OpenGL. Cela signifie que vous ne pouvez pas éviter l'appel à
glCompressedTexImage2D
un PBO lié. Cela étant dit, vous pouvez peut-être utiliser une texture RGBA 16 bits et un type d'image GLSL dans votre shader de calcul.Vous devez synchroniser la mémoire : pour vous assurer que votre shader de calcul termine l'écriture dans votre tampon de stockage, vous devez vous assurer que toutes les lectures et écritures y sont terminées. Cela se fait en appelant
glMemoryBarrier
avecGL_SHADER_STORAGE_BARRIER_BIT
.Le code complet de quelque chose qui écrit dans un tampon à utiliser comme texture compressée ressemble à ceci:
la source
GL_SHADER_STORAGE_BARRIER_BIT
Mauvaise barrière. La barrière que vous fournissez indique comment vous allez utiliser la mémoire. Pas comment le shader lui a écrit. Vous effectuez un transfert de pixels, vous devez donc utiliserGL_TEXTURE_UPDATE_BARRIER_BIT
GL_TEXTURE_UPDATE_BARRIER_BIT
est utilisé lors de la synchronisation des appels versglTexImage
, et n'a rien à voir avec la mémoire utilisée dans les tampons de stockage. Je pense que tu voulais direGL_PIXEL_BUFFER_BARRIER_BIT
?