微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 glfwDestroyWindow

如何解决在 glfwDestroyWindow

以下 OpenGL/GLFW/GLAD 代码(MCVE 版本)使进程崩溃,并在 nvoglv64.dll 中出现以下访问冲突异常:

0x00007FFC731F586F (nvoglv64.dll) in ConsoleApplication2.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x0000000000024AA8.

在下面代码清单末尾的 glfwDestroyWindow(window) 调用中,我不知道为什么。当不调用 glTexPageCommitmentARB 或使用 commitGL_FALSE/0 调用它时,此调用不会崩溃。

我已经阅读了 ARB_sparse_texture 的规范三遍,检查了 glTexPageCommitmentARB (x,y,z,width,height,depth内部格式的页面大小的倍数),我有点确定我已经遵循了有关如何正确使用该功能的所有说明。之前,我还使用调试上下文和调试消息回调检查了任何 OpenGL 错误,但没有任何输出

更多信息:

  • 操作系统:Windows 10 x64 (20H2)
  • 驱动程序:Nvidia 461.09 (DCH)
  • GLAD 配置:OpenGL 4.3 核心 + ARB_sparse_texture + ARB_sparse_texture2
  • GLFW:来自 Git 提交的全新本地 MSVC x64 Release 构建 0b9e48fa3df9c18

下面代码glTexPageCommitmentARB 调用之前的 fprintf 在程序结束崩溃前打印以下输出

256 128 1 32768
#include <stdlib.h>
#include <stdio.h>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
int main(int argc,char** argv) {
    glfwInit();
    glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MInor,3);
    glfwWindowHint(GLFW_VISIBLE,GLFW_FALSE);
    GLFWwindow* window = glfwCreateWindow(800,600,"",NULL,NULL);
    if (window == NULL) {
        fprintf(stderr,"%s\n","GLFW window NULL");
        exit(1);
    }
    glfwMakeContextCurrent(window);
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        fprintf(stderr,"gladLoadGLLoader Failed");
        exit(2);
    }
    if (!GLAD_GL_ARB_sparse_texture || !GLAD_GL_ARB_sparse_texture2) {
        fprintf(stderr,"GL_ARB_sparse_texture or GL_ARB_sparse_texture2 unsupported");
        exit(3);
    }
    gluint tex;
    glGenTextures(1,&tex);
    glBindTexture(GL_TEXTURE_2D,tex);
    // activate sparse allocation for this texture
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_SPARSE_ARB,GL_TRUE);
    // use default page size index 0 (as per ARB_sparse_texture2)
    glTexParameteri(GL_TEXTURE_2D,GL_VIRTUAL_PAGE_SIZE_INDEX_ARB,0);
    GLint width,depth,maxSparseTexSize;
    // query page size for width,height and depth
    // R16UI is supported as sparse texture internal format as per
    // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_sparse_texture.txt
    glGetInternalformativ(GL_TEXTURE_2D,GL_R16UI,GL_VIRTUAL_PAGE_SIZE_X_ARB,1,&width);
    glGetInternalformativ(GL_TEXTURE_2D,GL_VIRTUAL_PAGE_SIZE_Y_ARB,&height);
    glGetInternalformativ(GL_TEXTURE_2D,GL_VIRTUAL_PAGE_SIZE_Z_ARB,&depth);
    glGetIntegerv(GL_MAX_SPARSE_TEXTURE_SIZE_ARB,&maxSparseTexSize);
    fprintf(stderr,"%d %d %d %d\n",maxSparseTexSize);
    glTexStorage2D(
        /*target*/GL_TEXTURE_2D,/*levels*/1,/*internalFormat*/GL_R16UI,/*width*/maxSparseTexSize,/*height*/maxSparseTexSize);
    // commit one page at (0,0)
    glTexPageCommitmentARB(GL_TEXTURE_2D,/*level*/0,/*xoffset*/0,/*yoffset*/0,/*zoffset*/0,/*width*/width,/*height*/height,/*depth*/depth,/*commit*/GL_TRUE);
    glfwDestroyWindow(window);
    glfwTerminate();
}

在这里遗漏了什么,还是只是驱动程序或 GLFW 错误

编辑:更多信息: 崩溃发生在驱动程序线程 (nvoglv64.dll) 中,紧跟在为 GL 上下文调用 wglDeleteContext(...) 的主线程之后。当 Visual Studio 2019 调试器因异常而停止时,我可以看到存在三个驱动程序线程(全部来自 nvoglv64.dll)(其中一个发出访问冲突异常),而主线程在 wglDeleteContext(...) 之后立即停止。

EDIT2:对此进行更多实验,当纹理未取消引用(引用计数为 0)并在销毁 GL 上下文之前由驱动程序处理时,总是会发生崩溃。例如,在上面的代码中,当我在 glDeleteTextures(1,&tex); 之前调用 glDestroyWindow(window) 时,不会发生崩溃(可重现)。在我提取上述 MCVE 的实际应用程序中,纹理也作为颜色附件附加到 FBO 中。当我没有删除 FBO 而只是减少纹理的引用计数时(通过调用 glDeleteTextures(...),崩溃仍然会发生。只有当我还通过 {{1} 取消引用 FBO 时} 以及随之而来的纹理,是否不会再发生崩溃。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。