C++如何读取系统显卡显存大小?(OpenGL或Direct3D查询)

2次阅读

windows下用dxgi查询显存最可靠,通过idxgiadapter::getdesc获取dedicatedvideomemory字段;linux/macos无统一方案,opengl扩展不可靠,macos无公开接口

C++如何读取系统显卡显存大小?(OpenGL或Direct3D查询)

Windows 下用 DXGI 查询显存大小最可靠

Direct3D 11/12 的 DXGI 接口是 Windows 平台获取显存容量最稳定的方式,它绕过了驱动层差异,直接读取 GPU 设备的 IDXGIAdapter 属性。OpenGL 没有标准 API 获取显存总量,glGetString(GL_VENDOR) 或扩展如 GL_ATI_meminfo 都不通用,Linux/macOS 更无统一方案。

实操建议:

  • 必须初始化 COM(CoinitializeEx(nullptr, COINIT_APARTMENTTHREADED)),否则 CreateDXGIFactory1 失败
  • 遍历 IDXGIAdapter 时,跳过软件渲染器(检查 Description.VendorId != 0x1414
  • 显存分“专用显存”(dedicated video memory)和“共享系统内存”(shared system memory),关键字段是 DedicatedVideoMemorySharedSystemMemory
  • 示例关键代码:
    IDXGIFactory1* factory; CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory); IDXGIAdapter* adapter; factory->EnumAdapters(0, &adapter); // 第一块独显 DXGI_ADAPTER_DESC desc; adapter->GetDesc(&desc); // desc.DedicatedVideoMemory 即专用显存字节数

Linux 上只能靠 /sys/class/drm 推断,且不准

Linux 没有内核级 GPU 显存报告机制,NVIDIA 驱动不暴露总显存,AMDGPU 和 Intel i915 只在 /sys/class/drm/card0/device/mem_info_vram_total 等路径提供近似值,但该值常为 0 或仅反映当前分配量,不是硬件规格。

常见错误现象:

立即学习C++免费学习笔记(深入)”;

  • /sys/class/drm/card0/device/mem_info_vram_total 返回 0 —— 这不是 bug,是驱动未实现或权限不足
  • 误把 /proc/meminfo 里的 MemTotal 当显存 —— 完全无关
  • nvidia-smi --query-gpu=memory.total 得到的是当前可见显存,受 ECC、预留 BIOS 内存影响,比标称值小 10%~20%

OpenGL 扩展不可靠,别依赖 GL_NVX_gpu_memory_info

这个 NVIDIA 扩展返回的是当前可用显存,不是总容量,且只在部分驱动版本中启用;AMD 的 GL_ATI_meminfo 已废弃,Intel 完全不支持。调用 glGetIntegerv 前必须确认扩展存在,否则触发 GL_INVALID_ENUM 错误。

使用场景限制:

  • 仅适合做运行时显存水位监控,不能用于初始化资源预算
  • GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 返回值单位是 KB,但实际是估算值,误差可达 ±512MB
  • 跨平台项目若强制启用该扩展,Linux/macOS 下会静默失败,glGetError() 返回 0,但变量未赋值

macOS 完全没公开接口,连 hack 都难

Apple 从 macOS 10.15 开始移除了 IORegistryEntryCreateCFProperty 对 GPU 显存节点的访问权限,MTLCopyAllDevices 只返回设备型号,不包含内存信息。第三方工具如 system_profiler SPDisplaysDataType 是解析 GUI 配置文件,非实时硬件读取。

能做的只有:

  • system_profiler 输出并 parse(不稳定,格式随系统版本变)
  • 硬编码常见机型显存值(如 MacBook Pro M3 Max = 48GB,但仅限 Apple Silicon)
  • 放弃获取,改用运行时试探性分配 + MTLCommandBufferStatusError 回退

显存大小不是固定值:集成显卡共享内存可变,独显可能被 BIOS 截留一部分,Windows 上还受“Reserve video memory”设置影响。真要算资源上限,不如测 vkGetPhysicalDeviceMemoryPropertiesdeviceLocal heap size(Vulkan),它至少是驱动承认的可用总量。

text=ZqhQzanResources