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

标签 opengl

OpenGL 引用文献提到了 GL_OUT_OF_MEMORY 错误

The state of the GL is undefined, except for the state of the error flags, after this error is recorded.

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

这种情况真的没救了吗?如果出现此错误,我是否只能重新创建整个 OpenGL 上下文并重新开始?

最佳答案

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

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

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

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

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

当您调用分配函数时,不会(必然)分配内存。驱动程序可以(并且几乎肯定会)将分配推迟到以后。因此,无论您在驱动程序检测到 OOM 条件后调用什么 OpenGL 函数,都会收到 OOM 错误。

因此,如果缓冲区分配失败,在引发失败的 glBufferData 调用之后很长时间,OpenGL 规范对当前状态有何说明?仅从 OOM 错误来看,无法追查到底是什么原因造成的。

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

请注意,当您尝试分配内存但无法分配内存时,较低级别的 API(如 Vulkan 或 D3D12)将立即 OOM。

还有:

But on the other hand the API doesn't seem to provide any way to check if sending data of particular size would succeed.

那什么也解决不了。为什么?

因为您的应用程序不拥有 GPU;你的操作系统有。多个程序可以同时在 GPU 上分配内存。操作系统也可以使用内存,在它认为合适的时候将内容分页进出内存。

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

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

关于opengl - 如何在 glBufferData 期间处理 GL_OUT_OF_MEMORY 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43989605/

相关文章:

c++ - glslang 无法解析内置函数

java - libgdx 中不一致的颜色渐变绘制矩形/ Sprite

c++ - OpenGL:带三角剖分的贝塞尔曲面

opengl - 简单的程序天空盒

opengl - 解除绑定(bind) OpenGL 缓冲区有什么影响?

c - 在 OpenGL 中绘制二维纹理

opengl - 如何实现 OpenGL 缩放范围功能

opengl - 无法获取指定着色器类型的子例程信息

c++ - 反转 x 轴的透视投影 (glm::perspective)

c - OpenGL 在 OSX 上出现段错误,但在 Raspberry Pi 上运行良好