c++windowsqtopenglqopenglfunctions

How I can get my total GPU memory using Qt's native OpenGL?


I'm trying to get the total amount of GPU memory from my video card using native Qt's OpenGL, I have tried hundred of methods, but none do work. This is what I have at the moment:

  QOpenGLContext context;
  context.create();
  QOffscreenSurface surface;
  surface.setFormat(context.format());
  surface.create();
  QOpenGLFunctions func;
  context.makeCurrent(&surface);
  func.initializeOpenGLFunctions();
  GLint total_mem_kb = 0;
  func.glGetIntegerv(GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX,&total_mem_kb);
  qDebug()<<total_mem_kb;

The problem is that the variable total_mem_kb is always 0, It does not get the value inside of glGetIntegerv. By running this code I get 0. What can be the problem? Can you please give me a hint?


Solution

  • First an foremost check if the NVX_gpu_memory_info extension is supported.

    Note that the extension requires OpenGL 2.0 at least.

    GLint count;
    glGetIntegerv(GL_NUM_EXTENSIONS, &count);
    
    for (GLint i = 0; i < count; ++i)
    {
        const char *extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
        if (!strcmp(extension, "GL_NVX_gpu_memory_info"))
            printf("%d: %s\n", i, extension);
    }
    

    I know you just said that you have an Nvidia graphics card, but this doesn't by default guarantee support. Additionally if you have an integrated graphics card then make sure you are actually using your dedicated graphics card.

    If you have an Nvidia GeForce graphics card, then then the following should result in something along the lines of "Nvidia" and "GeForce".

    glGetString(GL_VENDOR);
    glGetString(GL_RENDERER);
    

    If it returns anything but "Nvidia" then you need to open your Nvidia Control Panel and set the preferred graphics card to your Nvidia graphics card.


    After you've verified it being the Nvidia graphics card and that the extension is supported. Then you can try getting the total and current available memory:

    GLint totalMemoryKb = 0;
    glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &totalMemoryKb);
    
    GLint currentMemoryKb = 0;
    glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &currentMemoryKb);
    

    I would also like to point out that the NVX_gpu_memory_info extension defines it as:

    GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX
    

    and not

    GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX
    

    Note the MEMORY vs MEM difference.

    So suspecting you've defined GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX yourself or leveraging something else that has defined it. That tells it could be wrongly defined or referring to something else.