例如,glTexImage2D
函数具有参数internalformat
,该参数指定纹理数据将在内部具有的格式。然后,GL驱动程序将通过format
、type
和data
参数转换我提供的数据。
许多来源(甚至是供应商的官方文件)都说,我提供的数据应该与内部格式相匹配。例如,来自Intel的本文档中的第33页:https://web.archive.org/web/20200428134853/https://software.intel.com/sites/default/files/managed/49/2b/Graphics-API-Performance-Guide-2.5.pdf
上载纹理时,请以与内部格式相同的格式提供纹理,以避免图形驱动程序中的隐式转换。
但我认为这种方法存在一些问题:
- 我只是不知道,什么是图形卡的本地格式。它可能是RGBA与10 bpp规范化整数,甚至一些真实的的异国情调的东西。所以司机无论如何都要做一个转换。OpenGL规范只是定义了一些内部格式,这些格式需要实现完全支持。但是当然,驱动程序可以将内部格式转换为一些其他“本机格式”。
- 在大多数情况下,我会从外部源加载我的纹理,格式,我没有太大的影响。所以我有两个选择在我自己的应用程序中编写一个转换图像数据的函数,或者让驱动程序来完成这项工作。在我看来,第二个选择是更好的选择。该驱动程序可能会有高度优化的转换算法实现,并会少得多的错误倾向比我自己的算法可能是,因为它已经非常好的测试。
那么,真的有必要为这些事情烦恼吗?或者直接向OpenGL提供数据就可以了吗?
1条答案
按热度按时间guykilcj1#
你最关心的不应该是上传一个图像到GPU所需的时间。
最大的瓶颈不是你只做一次的事情,而是你要重复做的事情。例如,如果超出驻留纹理的限制,则OpenGL实现可能会将纹理交换到主存中(这可能会成为瓶颈)。
但是如果你能够通过使用较低的位或压缩格式来节省内存,那么你就可以在GPU上保留更多的纹理,这将带来更好(更平滑)的性能。
还有一件事你还应该记住,你的应用程序并不是唯一一个获取GPU资源的应用程序。为了获得整体流畅的体验,只使用您需要的(最低限度),不要太贪心。
当然,使用千兆字节的GPU内存,需要很多才能将GPU带到极限,但这并不意味着没有限制。
在你的评论之后,我重新阅读了你的问题,我认为,我有点误解了它。
我想说的是,你认为驱动程序具有高度优化的转换例程,在兼容的颜色格式之间转换没有多大意义。
但在YUV到RGB转换的情况下,唯一的选择是为每个平面使用纹理(在着色器中进行计算)或将YUV转换为RGB三元组。HSV或CMYK颜色格式也是如此,在主机端进行转换是不可避免的。
同样,在兼容的格式中,让驱动程序完成工作,否则转换自己。
顺便说一句:
根据您使用的OpenGL堆栈,例如EGL允许您选择具有特定属性的帧缓冲区配置(请参阅:https://registry.khronos.org/EGL/sdk/docs/man/html/eglChooseConfig.xhtml-例如EGL_CONFIG_CAVEAT)。根据您选择的配置,您应该了解帧缓冲区的属性(位深度、颜色大小等)。