OpenGL帧缓冲附件泄漏GPU内存

Asy*_*lum 5 memory opengl framebuffer

请考虑以下测试代码:

for (int i = 0; i < 100; ++i) {
    GLuint fboid = 0;
    GLuint colortex = 0;
    GLuint depthtex = 0;

    // create framebuffer & textures
    glGenFramebuffers(1, &fboid);
    glGenTextures(1, &colortex);
    glGenTextures(1, &depthtex);

    glBindTexture(GL_TEXTURE_2D, colortex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4000, 4000, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);

    glBindTexture(GL_TEXTURE_2D, depthtex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 4000, 4000, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);

    glBindFramebuffer(GL_FRAMEBUFFER, fboid);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colortex, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthtex, 0);

    assert(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER));

    // clear it
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

    // delete everything
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, 0);

    glDeleteFramebuffers(1, &fboid);
    glDeleteTextures(1, &colortex);
    glDeleteTextures(1, &depthtex);
}

// put breakpoint here
Run Code Online (Sandbox Code Playgroud)

您将在活动监视器中看到底部的"Memory used"天空高(14 GB).好像GPU仍在引用已经发布的纹理.

我尝试了以下方法:

  • 在各个地方调用glFlush()
  • 在各个地方打电话给glFinish()
  • 更改纹理/ fbo删除的顺序
  • 删除前从fbo分离附件
  • call [context flushBuffer];

这些都没有任何影响.但是(!)如果我删除了glClear()调用,那么问题就会消失.

什么可能导致这个?它在Windows上也是可以重新编写的,并且还有另一个实现(不幸的是,我不能分享它,而且复杂得多).

有没有人看到像这样的内存泄漏问题?

更新:现在很明显,深度/模板缓冲区正在泄漏.如果我创建一个只有深度的附件,那么问题就会再次消失!

更新:使用英特尔卡更容易重现.在我2011年末的mbpro上,代码在使用分立卡(Radeon 6750M)时运行正常,但是使用集成卡(HD 3000)产生了所描述的泄漏.

更新:已在High Sierra(10.13.x)上修复

Asy*_*lum 0

虽然我没有找到任何合适的解决方案,但我想出了一个解决方法(不幸的是,这给 Radeon Pro 580(?)卡带来了不同的泄漏问题)

解决方法如下:

  • 首先,我启用 GL 上下文共享
  • 然后每当我想删除 D24S8 纹理时,我都会将其放入缓存中
  • 如果实现请求创建 D24S8 缓冲区,我首先查看缓存(不要忘记,MSAA 样本计数必须匹配!)
  • 如果缓存中有一个合适的项目(>=大于请求的大小),那么我将其取出并返回
  • 如果没有,那么我根据请求的大小创建一个

通过这个解决方案,我成功地最大限度地减少了上述配置的泄漏... aaaaaaa并将其弄乱了AMD卡(我认为这是另一种驱动程序错误,但现在我无法用小程序重现它)。