Committing first page of sparse texture crashes at glfwDestroyWindow

4

The following OpenGL/GLFW/GLAD code (MCVE version) crashes the process with the following access violation exception in nvoglv64.dll:

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

at the glfwDestroyWindow(window) call at the end of the code listing below, and I don't know, why. This call won't crash when either not calling glTexPageCommitmentARB or calling it with a commit of GL_FALSE/0.

I've read the specification of ARB_sparse_texture three times now, checking the conditions of every argument of glTexPageCommitmentARB (x, y, z, width, height, depth multiples of the page sizes of the internal format) and I am somewhat sure that I've followed all instructions on how to use that function correctly. I've also checked for any OpenGL errors with a debug context and a debug message callback before, there were no outputs.

Further information:

  • OS: Windows 10 x64 (20H2)
  • Driver: Nvidia 461.09 (DCH)
  • GLAD Configuration: OpenGL 4.3 Core + ARB_sparse_texture + ARB_sparse_texture2
  • GLFW: Fresh local MSVC x64 Release build from Git commit 0b9e48fa3df9c18

The fprintf right before the glTexPageCommitmentARB call in the code below print the following output before the crash at the end of the program:

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();
}

Am I missing anything here or is it just a driver or GLFW bug?

EDIT: Some more information: The crash happens in a driver thread (nvoglv64.dll) right after the main thread called wglDeleteContext(...) for the GL context. When the Visual Studio 2019 debugger halts due to the exception, I can see three driver threads (all from nvoglv64.dll) existing (one of which issued the access violation exception) while the main thread is halted right after wglDeleteContext(...).

EDIT2: Experimenting more with this, the crash always occurred when the texture was not dereferenced (ref count to 0) and disposed of by the driver before destroying the GL context. For example, in the code above, when I call glDeleteTextures(1, &tex); right before glDestroyWindow(window), the crash does not occur (reproducibly). In the actual app I distilled the above MCVE from, the texture was also attached as a color attachment in a FBO. When I did not deleted the FBO but only decremented the ref count for the texture (by calling glDeleteTextures(...), the crash would still occur. Only when I also dereferenced the FBO by glDeleteFramebuffers(...) and the texture along with it, would the crash not occur anymore.

c
opengl
glfw
glad
asked on Stack Overflow Jan 7, 2021 by Kai Burjack • edited Jan 8, 2021 by Kai Burjack

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0