OpenGL参考提及GL_OUT_OF_MEMORY
错误
在记录此错误后,GL的状态未定义,错误标志的状态除外。
如果函数glBufferData
无法消化给定数据,则会生成此错误。但另一方面,API似乎没有提供任何方法来检查发送特定大小的数据是否会成功。
这种情况真的无望吗?如果我收到此错误,那么我唯一能够重新创建整个OpenGL上下文并重新开始吗?
答案 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没有测试分配是否成功的功能的原因(也没有测试未分配多少内存的功能)。你只需分配内存;无论是有效还是你的记忆,或者它都失败了,你不会。