修改CUDA中的OpenGL FBO纹理附件



我有以下场景:

我有自定义的FBO与纹理作为颜色附件。我将我的东西渲染到FBO中。下一步,我需要与CUDA共享该纹理,然后在它上运行一些后处理内核。然后,纹理应绑定回全屏四边形,并渲染到默认的"帧缓冲区"。我已经阅读了几个OpenGL/CUDA互操作教程,其中的一些步骤我并不完全清楚

首先,我看到他们通常做的是从GL纹理X中读取数据,在CUDA中进行处理,然后使用PBO填充纹理Y和生成的数据。

我注意到的另一件事(如果我错了,请纠正我(是,这些演示中的OpenGL默认使用PBO绑定,这意味着第一次渲染结果存储在其中?我真的不确定,因为所有这些演示都使用固定的OpenGL,并且当渲染初始几何体过程时,我看不到PBO绑定的地方。

回到我的案例:我的最后一个问题是,我是否可以在不使用PBO的情况下直接在CUDA中对OpenGL纹理进行操作,以便在CUDA内核中对其进行修改?如果没有,那么这是否意味着我必须在将FBO纹理传递到CUDA阶段之前将其打包到PBO中?

更新:

从帧缓冲区填充PBO通常使用glReadPixels((完成,这意味着它被下载到CPU。这是我想防止的。-这是错误的假设。因此,基于我可以用纹理中的像素填充PBO的事实,下面的方法是什么?:使用来自纹理的数据填充PBO。

将其映射到CUDA缓冲区资源。

使用内核对数据进行更改。

从修改的PBO更新目标纹理。

在OpenGL中使用更新后的纹理。

以下是在CUDA中处理"OpenGL纹理",然后立即在OpenGL中使用它而无需额外开销的示例:

https://github.com/nvpro-samples/gl_cuda_interop_pingpong_st

从帧缓冲区填充PBO通常使用glReadPixels((完成,这意味着它被下载到CPU。这是我想防止的。

错了!

glReadPixels转换为PBO完全在GPU上执行,不往返于系统内存。

更新:

CUDA图形互操作有几个限制。例如,当图形资源在图形上下文中绑定时,不能将其映射到CUDA内存;具体来说,您可以映射它,但对它的任何访问都会产生未定义的结果。因此,通常的策略使用代理对象。

因此,如果所讨论的OpenGL资源由于任何原因无法解除绑定,那么使用PBO作为从OpenGL到CUDA的中介是一种很有价值的方法。然而,就FBO而言,这并不重要,因为只要绑定了FBO,就不能将绑定到FBO的任何内容用作数据源。由于这种限制,通常存在多个目标对象实例(渲染缓冲区或纹理(,以多缓冲区的方式循环使用。

因此,要么复制它,要么在将其映射到CUDA之前解除绑定。对于多个缓冲器,后者是优选的方法。

使用CUDA纹理时,在阅读时应始终写入不同的纹理(如果是纹理,则必须将其绑定到CUDA曲面(。

最新更新