我有以下管道:
- 渲染到自定义 FBO 的纹理附件。
- 将该纹理附件绑定为图像。
- 运行计算着色器,使用 imageLoad/Store 从上面的图像中采样。
- 将结果写入 SSBO 或图像。
- 将 SSBO(或图像)映射为 CUDA CUgraphicsResource并使用 CUDA 处理来自该缓冲区的数据。
现在,问题在于在第 4 阶段和第 5 阶段之间同步数据。这是我尝试过的同步解决方案。
glFlush - 并不能真正起作用,因为它不能保证所有命令执行的完整性。
glFinish - 这个工作。但不建议这样做,因为它会完成所有提交给驱动程序的命令。
glMemoryBarrier这个很有趣。但这根本行不通。
以下是代码示例:
glMemoryBarrier(GL_ALL_BARRIER_BITS);
并且还尝试过:
glTextureBarrierNV()
代码执行如下:
//rendered into the fbo...
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glBindImageTexture(imageUnit1, fboTex, 0, GL_FALSE, 0, GL_READ_ONLY,GL_RGBA8);
glBindImageTexture(imageUnit2, imageTex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8));
glDispatchCompute(16, 16, 1);
glFinish(); // <-- must sync here,otherwise cuda buffer doesn't receive all the data
//cuda maps the image to CUDA buffer here..
此外,我尝试在启动计算之前从上下文中解除绑定 FBO 和纹理,我什至尝试glMemoryBarrier
在它们之间启动一个计算,然后将目标图像从第一次计算启动获取到 CUDA。仍然没有同步。(嗯,这是有道理的,因为两个计算也彼此不同步)
在计算着色器阶段之后。不同步!只有当我替换为glFinish
, 或任何其他完全停止管道的操作时。比如glMapBuffer()
,例如。
那么我应该只使用glFinish(),还是我在这里遗漏了什么?为什么 glMemoryBarrier() 在 CUDA 接管控制之前不同步计算着色器工作?
更新
我想稍微重构一下这个问题,因为原来的问题已经很老了。尽管如此,即使使用最新的 CUDA 和视频编解码器 SDK (NVENC),问题仍然存在。所以,我不在乎为什么glMemoryBarrier
不同步。我想知道的是:
如果可以将 OpenGL 计算着色器执行完成与 CUDA 对该共享资源的使用同步,而不会停止整个渲染管道,在我的情况下是 OpenGL 图像。
如果答案是“是”,那该怎么做?