如何在glBufferData期间处理GL_OUT_OF_MEMORY错误?

时间:2015-12-10 14:34:25

标签: opengl

OpenGL参考提及GL_OUT_OF_MEMORY错误

  

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

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

这种情况真的无望吗?如果我收到此错误,那么我唯一能够重新创建整个OpenGL上下文并重新开始吗?

1 个答案:

答案 0 :(得分:15)

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

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

OpenGL也是如此。你可能有充分的理由要求特定的内存大小;因为你需要它如果你无法得到它,无论出于何种原因,通常都没有解决方案。

虽然有些情况下您可以从无法分配内存中恢复,但OpenGL会以另一种方式让您感到困惑。

请注意,在OUT_OF_MEMORY错误上未定义OpenGL的整个状态的原因是:OOM可以从任何地方发生。没有任何功能的文档声称它可以发出OOM错误,因为每个函数都可以发出这样的错误。

调用分配函数时,(必要)分配内存。司机可以(并且几乎肯定会)将分配推迟到以后。因此,在驱动程序检测到OOM条件后,您从调用的任何OpenGL函数中获得OOM错误。

因此,如果缓冲区分配失败,那么在调用glBufferData之后引发失败,那么OpenGL规范可以对当前状态说些什么呢?仅从OOM错误中,就无法确切地追踪导致它的原因。

因此,如果您收到此错误,则无法恢复。您唯一真正的办法是终止申请或重建申请。

请注意,当您尝试分配内存时,Vulkan或D3D12等较低级别的API会立即显示OOM。

此外:

  

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

这不会解决任何问题。为什么呢?

因为你的应用程序并不拥有 GPU;你的操作系统。多个程序可以同时在GPU上分配内存。操作系统也可以通过内存进行调整,在内存中调用内存和内存。

因此,如果您询问分配是否成功,并且OpenGL返回yes,那么当您实际执行该分配时,答案可能已已更改

这也是为什么Vulkan和类似的API没有测试分配是否成功的功能的原因(也没有测试未分配多少内存的功能)。你只需分配内存;无论是有效还是你的记忆,或者它都失败了,你不会。