我有以下情况:
我有自定义FBO纹理作为颜色附件。我将我的东西渲染到FBO.Next步骤我需要与CUDA共享该纹理,然后在其上运行一些后处理内核。之后纹理应该绑定回来全屏四边形并渲染为默认帧缓冲区。 我已阅读several OpenGL / CUDA interop tutorials,并且我这样做的一些步骤并不完全清楚。
首先,我看到他们通常做的是从GL纹理X读取数据,在CUDA中处理它,然后使用PBO填充纹理Y和结果数据。
我注意到的另一件事(如果我错了,请纠正我)是这些演示中的OpenGL使用默认绑定的PBO,这意味着第一次传递渲染结果存储在其中?我真的不确定它,因为所有这些演示都使用固定的OpenGL,并且在渲染初始几何传递时我看不到PBO被绑定的位置。
回到我的案例: 我的最后一个问题是 - 我可以直接在CUDA中使用OpenGL纹理而不使用PBO,这样我就可以在CUDA内核中修改它吗? 如果不是,那么它是否意味着我必须在将FBO纹理传递到CUDA阶段之前将其填充到PBO中?
更新
从帧缓冲区填充PBO通常使用glReadPixels()完成,这意味着它被下载到CPU。这是我想要防止的。 - 这是错误的假设。所以基于我可以用纹理填充PBO的事实是以下方式去? : 使用纹理数据填充PBO。
将其映射到CUDA缓冲区资源。
使用内核对数据进行更改。
从修改后的PBO更新目标纹理。
在OpenGL中使用更新的纹理。
答案 0 :(得分:1)
从帧缓冲区填充PBO通常使用glReadPixels()完成,这意味着它被下载到CPU。这是我想要防止的。
错!
glReadPixels进入PBO完全在GPU上执行,不会往返于系统内存。
CUDA-graphics互操作有几个限制。例如,当图形资源被绑定在图形上下文中时,您无法将图形资源映射到CUDA内存;特别是你可以映射它,但对它的任何访问都会产生不确定的结果。因此,通常的策略使用代理对象。
因此,如果有问题的OpenGL资源由于某种原因无法解除绑定,那么使用PBO作为从OpenGL到CUDA的中介是一种有价值的方法。然而,在FBO的情况下,它并不重要,因为无论绑定到FBO的什么都不能用作数据源,只要它受到限制。由于这种限制,通常存在多个目标对象(渲染缓冲或纹理)实例,以多缓冲方式循环使用。
所以要么你复制它,要么在将它映射到CUDA之前解除绑定。使用多个缓冲区后者是首选方法。
使用CUDA纹理时,您应该在读取时始终写入不同的纹理(在纹理的情况下,您必须将它们绑定到CUDA表面)。
答案 1 :(得分:1)
这是一个处理" OpenGL纹理"在CUDA中然后立即在OpenGL中使用它而没有额外的开销:
https://github.com/nvpro-samples/gl_cuda_interop_pingpong_st