在OpenGL中,不断上传新纹理到GPU会产生多大的开销?

5

不断地向GPU上传纹理(并替换旧的纹理)会带来多大的开销?我正在开发一个新的跨平台3D窗口系统,它使用OpenGL,并计划为每个窗口上传一个位图(包含UI元素)。该位图将与GPU同步更新(使用VSync)。我想知道这是否是个好主意,或者不断写入位图是否会造成太大的性能开销。谢谢!


为什么要在客户端渲染UI? - RecursiveExceptionException
2个回答

10

像nVidia的Geforce 460M这样的显卡本地内存带宽为60GB/sec。

PCI express 2.0 x16最大可管理8GB/sec的数据传输。

因此,如果您试图通过PCIe总线传输太多纹理,那么可能会遇到内存带宽问题。在60Hz的情况下,每帧可提供大约136兆字节的数据。未经压缩的24位1920x1080图像大小大约为6兆字节。因此,您可以在一个16x图形卡上上传几个视频帧。

当然这并不是那么简单。PCIe还有大约20%的开销。所有绘制指令也必须通过该连接上传。

总体上,只要您不过度使用,您就应该没有问题。请记住,在一帧中上传下一帧(或更晚)才会使用的纹理是明智的做法。这样,您就不会创建瓶颈,渲染将停止等待PCIe上传完成。


需要注意的是,普通的glTexImage会重新初始化纹理对象,因此存在开销。如果性能很重要,则应该使用glTexSubImage;对于像素缓冲区对象,应使用glBufferSubData + glTexSubImage。 - datenwolf
当总线已经饱和时,创建新纹理对象的CPU时间是否真的很重要? - Martin Beckett
可能会这样,因为创建一个新的纹理对象需要至少2个内存分配(实际上更可能是3个:一个用于数据结构,一个用于主内存中的位图,以及一个用于GPU内存中的位图)才能开始传输。传输的延迟不会隐藏这种开销,它会叠加在其上。此外,分配必须在应用程序线程以及系统上的所有线程之间进行同步,因为内存由所有内容共享,所以我不一定会将开销归类为“不可感知”的范畴。 - Damon
@dm.skt:幸运的是,可以通过在需要之前将纹理加载到GPU中来隐藏延迟... - Goz

0

最终,你的答案将会是性能分析。然而,在此之前,你可以进行一些早期的优化,例如在纹理没有发生变化时避免更新它。根据纹理的大小和像素格式,这可能会非常昂贵。

使用一个简单的情况来进行性能分析,模拟你所期望的使用方式。我怀疑(至少在没有我提到的优化的情况下)性能开销会非常大,如果你有几个更大的窗口,这取决于这些窗口的大小。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接