Opengl glBufferData期间,如何处理GLU OUT OUT(GLU出)内存错误?

Opengl glBufferData期间,如何处理GLU OUT OUT(GLU出)内存错误?,opengl,Opengl,OpenGL参考资料中提到了GL\u OUT\u OF\u MEMORY错误 记录此错误后,GL的状态未定义,错误标志的状态除外 如果函数glBufferData无法消化给定数据,则会生成此错误。但另一方面,API似乎没有提供任何方法来检查发送特定大小的数据是否会成功 这种情况真的没有希望吗?如果我遇到这个错误,我就只能重新创建整个OpenGL上下文并重新开始了吗?如果malloc返回NULL或new抛出异常,你会怎么做?对于这种可能性,你有恢复途径吗 大多数应用程序都没有。大多数应用程序愉快地

OpenGL参考资料中提到了
GL\u OUT\u OF\u MEMORY
错误

记录此错误后,GL的状态未定义,错误标志的状态除外

如果函数
glBufferData
无法消化给定数据,则会生成此错误。但另一方面,API似乎没有提供任何方法来检查发送特定大小的数据是否会成功


这种情况真的没有希望吗?如果我遇到这个错误,我就只能重新创建整个OpenGL上下文并重新开始了吗?

如果
malloc
返回NULL或
new
抛出异常,你会怎么做?对于这种可能性,你有恢复途径吗

大多数应用程序都没有。大多数应用程序愉快地假设
malloc
永远不会返回NULL和/或
new
永远不会抛出。如果这些操作失败,它们将很高兴崩溃

OpenGL通常也是如此。您可能是出于一个很好的理由要求特定的内存大小;因为你需要它。如果你不能得到它,无论出于什么原因,通常没有解决办法

虽然在某些情况下,您可以从无法分配内存中恢复,但OpenGL在另一方面让您感到困惑

请看,OpenGL的整个状态在内存不足错误中未定义的原因是:OOM可以在任何地方发生。没有函数的文档声称它可以发出OOM错误,因为每个函数都可以发出这样的错误

当您调用分配函数时,内存没有(必要)分配。司机可以(而且几乎肯定会)推迟分配到以后。因此,在驱动程序检测到OOM条件后,无论调用什么OpenGL函数,都会出现OOM错误

因此,如果缓冲区分配失败,在调用引发失败的
glBufferData
很久之后,OpenGL规范能对当前状态说些什么?仅仅从OOM错误来看,没有办法确切地找出它的原因

因此,如果您遇到此错误,恢复实际上是不可能的。您唯一真正的办法是终止应用程序或重建它

请注意,当您尝试分配内存时,Vulkan或D3D12等较低级别的API将立即发出OOM,但无法执行

此外:

但另一方面,API似乎没有提供任何方法来检查发送特定大小的数据是否会成功

那解决不了任何问题。为什么?

因为您的应用程序不拥有GPU;你的操作系统会。多个程序可以同时在GPU上分配内存。操作系统也可以使用内存,根据需要将内容分页到内存中或从内存中取出

因此,如果您询问分配是否会成功,OpenGL返回“是”,那么当您实际执行该分配时,答案可能已经改变


这也是为什么Vulkan和类似的API没有测试分配是否成功的功能(也没有测试未分配内存量的功能)。你只需要分配内存;要么它工作了,你就有了记忆,要么它失败了,你就没有了。

回答得很好。我只想补充一点,如果您能够确保回滚和清理不涉及额外的内存分配尝试,那么如果仔细设计应用程序,就有可能从内存不足的情况中恢复。一旦可以回溯到一个点,从这一点重新分配是可能的任何尝试。此外,新的低级API对于嵌入式和高可用性开发人员来说就像天赐良机。不过,返回分配的内存量的函数还是有用的。我目前正在调查OpenGL中的一个内存不足错误,我正在搜索某种统计函数,以便能够掌握漏洞。即使一个真正的OOM错误是不可处理的,在一个表现完美的应用程序和一个(缓慢)泄漏的应用程序之间也会有一个灰色世界。更糟糕的是,如果事先有一个GL错误,在调用
glGetError
之前不会记录更多的错误。因此,必须在有问题的函数调用之前清除它(从技术上讲,在循环中),出于性能原因,这在“设置”代码之外是不实际的。