在OpenGL中,缓冲区对象函数(glBufferDataglBufferSubData,可能还有其他一些)具有参数usage,该文件在文档中描述为预期用途的暗示,可能意在帮助实现更好的性能。


用法

指定数据存储的预期使用模式。符号常量必须是GL_STREAM_DRAWGL_STREAM_READGL_STREAM_COPYGL_STATIC_DRAWGL_STATIC_READGL_STATIC_COPYGL_DYNAMIC_DRAWGL_DYNAMIC_READGL_DYNAMIC_COPY。用法是GL实现关于缓冲区对象数据存储方式的提示。被访问。这使GL实现可以做出更明智的决策,从而可能显着影响缓冲区对象的性能。但是,它并不限制数据存储的实际使用。


维基同样含糊不清:


这些只是提示,毕竟。在创建STATIC缓冲区后修改它,或者永远不要修改STREAM缓冲区,这是完全合法的OpenGL代码。[...]
这些问题只能通过仔细分析来回答。即便如此,答案也仅对来自特定硬件供应商的特定驱动程序版本才是正确的。


好吧,如果有的话,此参数的相关性如何?驾驶员是否真的考虑到了这一点,如果您这样做了,根据您的经验,它在实践中会对性能产生多大影响?您有数据要共享吗?

我已经编写了一个薄的图形API抽象层,打算将其作为现有API中的任何一个实现,并且很想完全忽略此参数并将其隐藏在公开的抽象。

#1 楼

不同的实现会有所不同,但是我研究的驱动程序确实使用了这些驱动程序,主要是用来确定内存布局。这些提示所启用的优化比您想要的要小得多,这主要是因为您可以使用给出的任何提示进行限制。例如如果根本无法写入提示仅用于读取访问的缓冲区,则可使缓存失效的成本大大降低,但是这种优化是不可能的。

一些在GPU之间进行基准比较的著名游戏不能正确使用这些提示,因此GPU供应商有动力快速使用所有提示,即使它们与提示不匹配。

#2 楼

在功能上它们是相同的。

驾驶员可以使用它们来区分如何处理后台缓冲区。例如static_draw会尽快复制到vram并留在那儿,但是stream_read会始终在RAM中保留日期副本。

这种模糊性是glBufferStorage变成东西的原因。这样,您可以指定要对缓冲区执行的操作(是否通过BufferSubData更新缓冲区,是否通过映射进行读取或写入,映射的一致性如何,映射是否可以在整个使用过程中持续存在)超出这些界限是错误的。