2

我有以下情况:

我有带有纹理作为颜色附件的自定义 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 中使用更新的纹理。

4

2 回答 2

1

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

错误的!

glReadPixels 到 PBO 完全在 GPU 上执行,不会往返于系统内存。

更新:

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

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

因此,要么复制它,要么在将其映射到 CUDA 之前取消绑定它。对于多个缓冲区,后者是首选方法。

使用 CUDA 纹理时,您应该始终在读取时写入不同的纹理(在纹理的情况下,您必须将它们绑定到 CUDA 表面)。

于 2013-02-24T17:08:39.020 回答
1

这是在 CUDA 中处理“OpenGL 纹理”然后立即在 OpenGL 中使用它而没有额外开销的示例:

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

于 2015-05-12T18:16:09.447 回答