将某些顶点检索到 CPU 中的最快跨平台方法是什么?



我正在开发一个应用程序,我将相机姿势传递给 GPU,GPU 将生成包含有关对象可见顶点的不同信息的纹理(法线深度...... 根据这些信息,我想选择一些顶点并浏览生成的纹理,将这些顶点的所有信息检索到 CPU 中。

我已经做了一些阅读,最好的方法似乎是使用Trasform反馈。 但是,许多人似乎不赞成这里或此博客的最后一条评论,并选择计算着色器。

转换反馈机制不是您的解决方案。它适用于在 GPU 上捕获数据的当前状态并为 GPU 上的下一次绘制调用更新它,而无需为了数据更新而对 CPU 和后退乒乓球执行 GPU。粒子渲染是转换收费的常见用例之一。 您还没有说明您的目标平台是什么,因此很难理解您的硬件限制/功能,但这里有几种方法可以在不停止渲染管道的情况下下载主机 (CPU) 更新:

  1. 使用乒乓球。如果可以将数据写入纹理,则可以使用像素缓冲区对象异步下载以及从/上传到 GPU。如果您阅读了链接中的文档,您还可以看到,您可以使用共享上下文的线程传输更进一步。这些技术大大加快了传输时间。

  2. 如果您使用缓冲区,并且可以访问持久映射功能(OpenGL 4.4),则可以尝试双重甚至三重缓冲,如上所述,这是一种"PBO 乒乓球",但使用缓冲区。这里详细解释了这个概念,但一般的想法是持久映射一个缓冲区,大小的 3 倍,每一帧从主机上的 3 个部分之一读取,同时写入设备上 3 个部分的另一个部分。固定内存块对 GPU 是可见的,可能通过 DMA,虽然一般来说,持久映射缓冲区并不比常规映射快,但它们确实会显着减少每次帧更新的驱动程序开销。

  3. 重佳能,如在单独的线程中使用 CUDA 或 OpenCL。我不知道 OpenCL 是如何完成的,但是使用 CUDA,您可以在单独的线程中设置 CUDA 上下文,将缓冲区或纹理等 GL 资源映射到 CUDA 拥有的资源,然后使用生产者 - 消费者范式从 CUDA 映射的 GL 缓冲区读取数据以托管,同时继续在 OpenGL 线程中呈现。当然,您必须在线程之间同步,因为OpenGL在映射到CUDA上下文时不应访问缓冲区,因为此类访问的结果将是未定义的。

我个人会选择选项 2 + 使用共享上下文和线程作为持久映射的指针以读出数据。它在同步方面有其复杂性,但如果做得好,可以为您提供非常快速的解决方案。

最新更新