OpenGL 帧缓冲区附件泄漏 GPU 内存

标签 opengl memory framebuffer

考虑以下 test code :

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

您将在事件监视器中看到底部的“已用内存”变高 (14 GB)。好像 GPU 仍在引用已发布的纹理。

我尝试了以下方法:
  • 在不同的地方调用 glFlush()
  • 在不同的地方调用 glFinish()
  • 更改纹理/fbo 删除的顺序
  • 删除前从 fbo 中分离附件
  • 调用[上下文flushBuffer];

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

    什么可能导致这种情况?它也可以在 Windows 上重现,并且可以使用另一种实现(不幸的是,我无法共享它并且无论如何都要复杂得多)。

    你们有没有见过这样的内存泄漏问题?

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

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

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

    最佳答案

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

    解决方法如下:

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

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

    关于OpenGL 帧缓冲区附件泄漏 GPU 内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48226659/

    相关文章:

    空指针的 C 动态数组

    c++ - SDL_CreateRGBSurfaceFrom/SDL_BlitSurface - 我在模拟器上看到旧帧

    c++ - "glm::translate"输出一个包含不正确值的矩阵

    c++ - 获取对象空间到纹理空间的切线

    c - 如何实现glMultMatrixf

    opengl - glCopyTexImage2D 将其像素保存到哪里?

    c++ - Valgrind:来自复制构造函数的大小为 8 的无效写入

    memory - 如何从 Linux 中给定任务的用户空间进程获取页面?

    c++ - OpenGL 3.0 : Cannot use framebuffer object in shader (black)

    Linux DRM ( DRI ) 无法像以前一样使用 FBDEV 屏蔽 Scrape/dev/fb0