CUDA和OpenGL互操作类型

问题描述:

我正在进行3D模拟(现在是2D),我正在使用CUDA进行计算,OpenGL进行渲染。我的问题涉及CUDA和OpenGL之间的互操作性。 据我所见,有两种一般的方法可以做到这一点:CUDA和OpenGL互操作类型

第一个将使用映射到CUDA全局内存然后复制到其中的像素缓冲区对象(或顶点缓冲区对象)一个OpenGL纹理。据说这是一种非常快速的方法。

第二个是将纹理对象直接复制到CUDA纹理内存。这也将是非常好的,因为我可以使用纹理内存的所有功能,如纹理缓存等。

现在,有人可以向我解释这两种方法之间的一般差异是什么?而且他们每个人通常使用什么样的情况?

整个区别就像你说的,在纹理缓存中。因此,在这些方法之间进行选择取决于您是否要在可视化中利用纹理缓存。让我们来看一些常见的情况:

a)如果你想要计算一个曲面如何变形(例如水面或者一些弹性变形),你需要知道曲面的多边形网格的新顶点那么你通常会使用缓冲区(第一),除非你不需要在这里复制到OpenGL纹理。事实上,这里不涉及复制,你只需在CUDA中引用缓冲区并将其用作gl缓冲区。 b)如果你有一个粒子模拟,并且需要知道更新粒子的位置,那么你也可以像上述情况那样使用一个缓冲区。 c)如果你有一个有限元网格模拟,其中空间中的每个固定体积的单元格将获得一个新的值,并且你需要通过体绘制或等值面对其进行可视化,在这里你会想使用一个纹理对象(2D或3D,这取决于你的模拟的维度),因为当你投射光线,或者甚至产生流线时,你几乎总是需要立即使相邻纹理元素缓存。你可以避免在这里进行任何复制,就像上面的方法一样,你也可以直接从OpenGL引用一些CUDA纹理内存(cudaArray)。你可以使用这些调用来做到这一点:

cudaGraphicsGLRegisterImage(&myCudaGraphicsResource, textureNameFromGL, GL_TEXTURE_3D,...) 
... 
cudaGraphicsMapResources(1, myCudaGraphicsResource) 
cudaGraphicsSubResourceGetMappedArray(&mycudaArray, myCudaGraphicsResource, 0, 0) 
cudaGraphicsUnMapResources(1, myCudaGraphicsResource) 

所以这个质地CUDA数据可以通过mycudaArray引用而在OpenGL这个相同的内存可以通过textureNameFromGL引用。

从缓冲区复制到纹理中是一个坏主意,因为如果您需要此数据进行纹理缓存,您将执行额外的复制。在纹理互操作被支持之前,这在早期版本的CUDA中更受欢迎

您也可以在a)和b)用例中使用纹理。有些硬件甚至可能运行得更快,但这是非常依赖硬件的。请记住,纹理阅读也适用缩小和放大过滤器,这是额外的工作,如果你正在寻找的是一个存储在缓冲区中的确切值。

对于CUDA和OpenGL请参阅本样本

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

共享纹理资源