【问题标题】:Types of Cuda & OpenGL interopCuda 和 OpenGL 互操作的类型
【发布时间】:2013-04-30 19:06:33
【问题描述】:

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

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

第二个是将纹理对象直接复制到 CUDA 纹理内存。这也很好,从那时起我可以使用纹理缓存等所有纹理内存功能。

现在,有人可以向我解释这两种方法之间的一般区别是什么吗?以及它们各自通常用于什么样的情况?

【问题讨论】:

    标签: opengl cuda


    【解决方案1】:

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

    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

    【讨论】:

      猜你喜欢
      • 2011-09-22
      • 2011-12-03
      • 2013-10-15
      • 2013-04-04
      • 2016-01-25
      • 2011-07-23
      • 2014-05-11
      • 2015-08-03
      相关资源
      最近更新 更多