将某些顶点复制到主机的最快跨平台方法是什么?

问题描述 投票:0回答:1

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

我已经阅读了一些内容,最好的方法似乎是使用转换反馈。 然而,许多人似乎不赞成像这里的最后一条评论这个博客并选择计算着色器。

opengl glsl gpgpu
1个回答
0
投票

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

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

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

  3. 重规范,例如在单独的线程中使用 CUDA 或 OpenCL。我不知道 OpenCL 是如何完成的,但是使用 CUDA,您可以在单独的线程中设置 CUDA 上下文,将 GL 资源(如缓冲区或纹理)映射到 CUDA 拥有的资源,然后使用生产者 - 消费者范例从 CUDA 读取数据到主机映射GL缓冲区,同时保持在OpenGL线程中渲染。当然,您必须在线程之间进行同步,因为 OpenGL 在映射到 CUDA 上下文时不应该访问缓冲区,因为此类访问的结果将是不确定的。

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

© www.soinside.com 2019 - 2024. All rights reserved.