4

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

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

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

我现在已经阅读了三遍 ARB_sparse_texture的规范,检查了(x、y、z、宽度、高度、内部格式的页面大小的深度倍数)的每个参数的条件glTexPageCommitmentARB,我有点确定我已经遵循有关如何正确使用该功能的所有说明。我之前也用调试上下文和调试消息回调检查了任何 OpenGL 错误,没有输出。

更多信息:

下面代码中调用之前的 fprintfglTexPageCommitmentARB在程序结束时在崩溃之前打印以下输出:

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, "%s\n", "gladLoadGLLoader failed");
        exit(2);
    }
    if (!GLAD_GL_ARB_sparse_texture || !GLAD_GL_ARB_sparse_texture2) {
        fprintf(stderr, "%s\n", "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, height, 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_R16UI, GL_VIRTUAL_PAGE_SIZE_Y_ARB, 1, &height);
    glGetInternalformativ(GL_TEXTURE_2D, GL_R16UI, GL_VIRTUAL_PAGE_SIZE_Z_ARB, 1, &depth);
    glGetIntegerv(GL_MAX_SPARSE_TEXTURE_SIZE_ARB, &maxSparseTexSize);
    fprintf(stderr, "%d %d %d %d\n", width, height, depth, maxSparseTexSize);
    glTexStorage2D(
        /*target*/GL_TEXTURE_2D,
        /*levels*/1,
        /*internalFormat*/GL_R16UI,
        /*width*/maxSparseTexSize,
        /*height*/maxSparseTexSize);
    // commit one page at (0, 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 错误?

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

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

4

0 回答 0