我有一个Marching Cubes的GPU实现,它使用一系列6个GL计算着色器,每个读取缓冲区由相应的内存屏障后写入的缓冲区。早期阶段使用的缓冲区包含临时标记变量,应该在不再需要时调整为0,但不会删除,因为我将再次想要它们以便以后运行。
在某些阶段,我需要从着色器中的缓冲区读取,然后在着色器完成后立即释放它,然后为下一个着色器阶段分配缓冲区。我的问题是如何安全地做到这一点。内存屏障文档讨论了在允许另一个着色器读取之前确保所有写入都已完成,但在第一个着色器中没有说明读取。
如果我这样做:
HTTPS
glUseProgram(firstShader);
glDispatchCompute(size,1,1);
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
glNamedBufferData(firstBuffer,0,NULL,GL_DYNAMIC_DRAW);
glNamedBufferData(secondBuffer,1000000,&data,GL_DYNAMIC_DRAW);
glUseProgram(secondShader);
glDispatchCompute(size,1,1);
保证在firstBuffer
读完之前不会调整大小?如果没有,我该如何实现?
答案 0 :(得分:0)
并且应该在不再需要时调整为0,但不会删除,因为我再次希望它们再次运行。
调整缓冲区大小等同于删除缓冲区并在同一个id上分配新缓冲区。
在某些阶段,我需要从着色器中的缓冲区读取,然后在着色器完成后立即释放它,然后为下一个着色器阶段分配缓冲区。我的问题是如何安全地做到这一点。
删除它。删除第一阶段中的缓冲区只会删除id。 id只是对实际缓冲区对象的另一个引用。调整大小或删除缓冲区时,只会切断id与实际缓冲区之间的关联。调整大小实际上会创建一个新缓冲区并将id与其重新关联。实际上,调用glBufferData
将执行相同的操作(与glBufferSubData
相反)。这被称为“孤儿”。
实际缓冲区一旦最后一次引用(通过使用或来自id)就会被释放。