【问题标题】:Get results of GPU calculations back to the CPU program in OpenGL将 GPU 计算的结果返回到 OpenGL 中的 CPU 程序
【发布时间】:2012-12-14 17:55:30
【问题描述】:

有没有办法将运行在 GPU 上的着色器的结果返回到运行在 CPU 上的程序?

我想根据 GPU 上的计算成本高的算法从简单的体素数据生成多边形网格,但我需要 CPU 上的结果用于物理计算。

【问题讨论】:

标签: opengl cpu shader video-card


【解决方案1】:

定义“结果”?

一般来说,如果您使用 OpenGL 进行 GPGPU 风格的计算,您将需要围绕渲染系统的需求来构建着色器。渲染系统被设计成单向的:数据进入其中并生成图像。倒退,让渲染系统产生数据,通常不是渲染系统的结构。

当然,这并不意味着你不能这样做。但是您需要围绕 OpenGL 的限制来构建所有内容。

OpenGL 提供了许多挂钩,您可以在其中写入来自某些着色器阶段的数据。其中大部分都需要专门的硬件

片段着色器输出

任何支持片段着色器的硬件显然都允许您写入当前正在渲染的帧缓冲区。通过使用framebuffer objects 和带有浮点或整数的纹理image formats,您可以将几乎任何您想要的数据写入各种图像。一旦进入纹理,您可以简单地调用glGetTexImage 来获取渲染的像素数据。或者,如果 FBO 仍处于绑定状态,您可以通过 glReadPixels 获取它。无论哪种方式都有效。

此方法的主要限制是:

  • 可以附加到帧缓冲区的图像数量;这限制了您可以写入的数据量。在 GL 3.x 之前的硬件上,FBO 通常仅限于 4 个图像加上一个深度/模板缓冲区。在 3.x 和更好的硬件中,您可以预期最少 8 个图像。

  • 您正在渲染的事实。这意味着您需要设置顶点数据以将三角形准确定位在您希望它修改数据的位置。这不是一项微不足道的工作。获得有用的输入数据也很困难,因为您通常希望每个纹素彼此相当独立。围绕这些限制构建片段着色器是很困难的。并非不可能,但在许多情况下并非微不足道。

转换反馈

此 OpenGL 3.0 功能允许将来自 OpenGL 的Vertex Processing 阶段的输出(顶点着色器和可选的几何着色器)捕获到一个或多个缓冲区对象中。

这对于捕获您想要播放或再次渲染的顶点数据来说更加自然。在您的情况下,您需要在渲染后将其读回,可能使用glGetBufferSubData 调用,或使用glMapBufferRange 进行读取。

这里的限制是您通常只能捕获 4 个输出值,其中每个值都是一个 vec4。还有一些严格的布局限制。一些 OpenGL 3.x 和 4.x 硬件提供了将数据写入多个反馈流的能力,这些反馈流都可以写入不同的缓冲区。

图像加载/存储

此 GL 4.2 功能代表了写入的巅峰:您可以绑定图像(如果要写入缓冲区,则为缓冲区纹理),然后直接写入。您需要在 memory ordering constraints 中工作。

它非常灵活,但也非常复杂。除了难以正确使用它之外,还有许多限制。您可以写入的图像数量相当有限,可能是 8 个左右。并且实现可能有总写入限制,因此要写入的 8 个图像可能必须由片段着色器的输出共享。

此外,仅片段着色器(和 4.3 的计算着色器)保证图像输出。也就是说,允许硬件禁止您在非 FS/CS 着色器阶段使用图像加载/存储。

【讨论】:

  • 对此我有两个疑问:1)一般情况下,使用Transform Feedback从顶点处理阶段写出顶点数据后,写入的数据在GPU内存中,而不是传输到主内存中,除非调用了glGetBufferSubDataglMapBufferRange,对吗? 2) 如果变换反馈和图像加载/存储仅在 GPU 内存上运行,它们是否同样快,或者是一种方式比另一种方式快?它们是使用相同类型的 GPU 内存还是在不同类型上运行?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-25
相关资源
最近更新 更多