glClear() 在 Intel HD 4000 (GL 4.0) 上提供 GL_OUT_OF_MEMORY 而不是 GeForce (GL 4.2) ......为什么?

met*_*eap 5 opengl framebuffer go render-to-texture

现在,这是一种非常奇怪的行为。

TL;DR——在渲染到纹理设置中,在调整窗口(帧缓冲区 0)大小时,只有下一次调用glClear(GL_COLOR_BUFFER_BIT)绑定帧缓冲区 0(窗口的客户区)会给出GL_OUT_OF_MEMORY,仅在两个中的一个GPU,但是渲染仍然正确且正确地进行。

现在,所有重要的细节:

所以这是在带有两个 GPU 的 Vaio Z 上(可以通过机器上的物理切换按钮切换到):

  1. OpenGL 4.2.0 @ NVIDIA Corporation GeForce GT 640M LE/PCIe/SSE2(GLSL:4.20 NVIDIA 通过 Cg 编译器)

  2. OpenGL 4.0.0 - Build 9.17.10.2867 @ Intel Intel(R) HD Graphics 4000 (GLSL: 4.00 - Build 9.17.10.2867)

我的程序在使用 GLFW 64 位的 Win 7 64 位下的 Go 1.0.3 64 位。

我有一个相当简单直接的渲染到纹理“迷你管道”。首先,普通 3D 几何体使用最简单的着色器(没有照明,什么都没有,只有纹理三角形网格,它们只是一些立方体和平面)渲染到具有深度/模板渲染缓冲区作为深度/模板附件和texture2D 作为颜色附件。对于纹理,所有过滤都被禁用,mip-maps 也是如此。

然后我渲染一个全屏四边形(实际上是一个“超大”全屏三边形),只是从带有 texelFetch(tex, gl_FragCoord.xy, 0) 的所述帧缓冲区纹理(颜色附件)中采样,因此不使用包装。

两个 GPU 都可以很好地呈现这一点,无论是在我强制执行核心配置文件还是不执行核心配置文件时。没有为此报告任何 GL 错误,所有渲染也按预期进行。除非我在使用 Intel HD 4000 GPU 的 GL 4.0 渲染器(在 Core 配置文件和 Comp 配置文件中)时调整窗口大小。只有在这种情况下,在帧缓冲区 0(屏幕)上的下一次 glClear(GL_COLOR_BUFFER_BIT) 调用之后,单个调整大小将直接记录 GL_OUT_OF_MEMORY 错误,但仅在调整大小后记录一次,而不是在每个后​​续循环迭代中。

有趣的是,我实际上并没有对调整大小进行任何分配!我暂时禁用了窗口调整大小时发生的所有逻辑——也就是说,现在我只是完全忽略了窗口调整大小事件,这意味着 RTT 帧缓冲区及其深度和颜色附件分辨率甚至没有更改/重新创建。这意味着下一个 glViewPort 仍将使用与第一次创建窗口和 GL 上下文时相同的尺寸,但是任何错误都发生在 glClear() 上(不是之前,只有之后,只有一次 - 我已经双重和三次检查)。

这是一个驱动程序错误,还是我在这里做错了什么?

met*_*eap 2

HD 的 GL 驱动程序中出现了一个有趣的故障,看起来:

当我切换到渲染到纹理设置时,我还在 GL 上下文创建时将主帧缓冲区 0(即屏幕/窗口)的深度/模板位设置为 0。这是我开始看到此错误并且与之前相比,帧率变得相当缓慢。

我实验性地将(严格来说不需要的)深度位设置为 8,这两个问题都消失了。因此,当前的 HD 4000 GL 4.0 驱动程序版本似乎不喜欢在 GL 上下文创建时将其深度缓冲区位设置为 0。