如何使用Qt的原生OpenGL获取我的总GPU内存?

时间:2017-04-07 00:01:31

标签: c++ windows qt opengl qopenglfunctions

我试图使用原生Qt的OpenGL从我的视频卡中获取GPU内存总量,我已经尝试了数百种方法,但没有一种方法可行。 这就是我现在所拥有的:

  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.可能是什么问题?你能给我一个提示吗?

2 个答案:

答案 0 :(得分:2)

首先检查是否支持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);

如果它返回“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或者利用定义它的其他东西。这说明它可能被错误地定义或引用其他东西。

答案 1 :(得分:0)

我使用以下内容:

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