如何使用 Qt 的本机 OpenGL 获取我的总 GPU 内存?

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

我正在尝试使用本机 Qt 的 OpenGL 从我的视频卡获取 GPU 内存总量,我尝试了数百种方法,但 none 确实有效。 这是我目前拥有的:

  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;

问题是变量total_mem_kb一直是0,它没有得到glGetIntegerv里面的值。通过 运行 这段代码我得到 0。可能是什么问题?你能给我一个提示吗?

首先检查是否支持 NVX_gpu_memory_info 扩展。

请注意,该扩展至少需要 OpenGL 2.0。

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

我知道您刚才说您有 Nvidia 显卡,但这并不能默认保证支持。此外,如果您有集成显卡,请确保您实际使用的是独立显卡。

如果您有 Nvidia GeForce 显卡,那么下面的结果应该类似于 "Nvidia" 和 "GeForce"。

glGetString(GL_VENDOR);
glGetString(GL_RENDERER);

如果 returns 除了 "Nvidia" 之外,您需要打开 Nvidia 控制面板并将首选显卡设置为您的 Nvidia 显卡。


在您确认它是 Nvidia 显卡并且扩展程序受支持后。然后你可以尝试获取总的和当前的可用内存:

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

我还想指出 NVX_gpu_memory_info 扩展将其定义为:

GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX

而不是

GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX

注意 MEMORYMEM 的区别。

所以怀疑您自己定义了 GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX 或利用了定义它的其他东西。这表明它可能被错误定义或引用其他内容。

我使用以下:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////   
LONG __stdcall glxGpuTotalMemory()
{
    GLint total_mem_kb = 0;
    glGetIntegerv(GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX, &total_mem_kb);

    if (total_mem_kb == 0 && wglGetGPUIDsAMD)
    {
        UINT n = wglGetGPUIDsAMD(0, 0);
        UINT *ids = new UINT[n];
        size_t total_mem_mb = 0;
        wglGetGPUIDsAMD(n, ids);
        wglGetGPUInfoAMD(ids[0], WGL_GPU_RAM_AMD, GL_UNSIGNED_INT, sizeof(size_t), &total_mem_mb);
        total_mem_kb = total_mem_mb * 1024;
    }

    return total_mem_kb;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////   
LONG __stdcall glxGpuAvailMemory()
{
    GLint cur_avail_mem_kb = 0;
    glGetIntegerv(GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX, &cur_avail_mem_kb);

    if (cur_avail_mem_kb == 0 && wglGetGPUIDsAMD)
    {
        glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, &cur_avail_mem_kb);
    }

    return cur_avail_mem_kb;
}