【问题标题】:How I can get my total GPU memory using Qt's native OpenGL?如何使用 Qt 的原生 OpenGL 获得总 GPU 内存?
【发布时间】:2017-09-02 05:16:12
【问题描述】:

我正在尝试使用原生 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。可能是什么问题?可以给个提示吗?

【问题讨论】:

  • @Vallentin,我见过那个,不一样。 glGetString 对我来说工作得很好,但上面的代码不能正常工作。
  • 您能否更具体地说明“不工作”。请注意,GL_NVX_gpu_memory_info 是 Nvidia 扩展。因此,如果您的显卡不是 Nvidia,那么支持此扩展的可能性很小。
  • @Vallentin, "not working" - 不初始化 glGetIntegerv 函数内的变量 total_mem_kb。 Nvidia 驱动程序在一小时前更新,我只是不知道为什么这“不起作用”

标签: c++ windows qt opengl qopenglfunctions


【解决方案1】:

我使用以下:

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

【讨论】:

    【解决方案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 或利用了其他定义它的东西。这表明它可能被错误地定义或引用了其他东西。

    【讨论】:

    • glGetString(GL_VENDOR) = 结果是“英特尔”。为什么说英特尔?
    • 那么这说明您使用的是集成显卡,而不是您的专用 Nvidia 显卡。
    • 但是我怎样才能得到 Nvidia 的显卡信息呢?我已经切换了GPU,现在Qt运行在Nvidia卡上而不是Intel上,结果是一样的。
    • 这是个问题吗?还是你刚才说GL_VENDOR 现在说的是“Nvidia”?
    • 不,每个函数调用和扩展都与上下文正在使用的 GPU 相关。以便选择您的 Nvidia 显卡。打开您的 Nvidia 控制面板并将首选显卡设置为您的 Nvidia 显卡。
    猜你喜欢
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-15
    • 2015-11-12
    相关资源
    最近更新 更多