在DirectX 11中如何获取适配器可用/已用内存量?
DirectX 11 获取显存使用情况的可行方案
DirectX 11确实没有提供和DirectX 9中IDirect3DDevice9::GetAvailableTextureMem()直接等效的API,但可以通过以下几种方式实现类似需求:
1. 使用Windows性能计数器(PDH API)
Windows任务管理器的GPU内存统计就是基于这套机制,实时性和准确性都有保障。核心是通过Performance Data Helper (PDH) API读取系统提供的GPU性能计数器:
- 关键函数包括:
PdhOpenQuery、PdhAddCounter、PdhCollectQueryData、PdhGetFormattedCounterValue - 常用的计数器路径示例:
- 单GPU的专用显存已用:
\GPU Memory(0)\Dedicated Usage - 所有GPU的专用显存已用:
\GPU Memory(*)\Dedicated Usage - 显存空闲可通过总显存(
DXGI_ADAPTER_DESC.DedicatedVideoMemory)减去已用显存计算
- 单GPU的专用显存已用:
代码片段示例:
#include <pdh.h> #pragma comment(lib, "pdh.lib") bool GetGPUMemoryUsage(unsigned long long& dedicatedUsed) { PDH_HQUERY query = NULL; PDH_HCOUNTER counter = NULL; PDH_FMT_COUNTERVALUE value; if (PdhOpenQuery(NULL, NULL, &query) != ERROR_SUCCESS) { return false; } // 替换为对应GPU的计数器路径,可枚举所有GPU计数器路径适配不同设备 if (PdhAddCounter(query, L"\\GPU Memory(0)\\Dedicated Usage", NULL, &counter) != ERROR_SUCCESS) { PdhCloseQuery(query); return false; } if (PdhCollectQueryData(query) != ERROR_SUCCESS) { PdhRemoveCounter(counter); PdhCloseQuery(query); return false; } if (PdhGetFormattedCounterValue(counter, PDH_FMT_LARGE, NULL, &value) == ERROR_SUCCESS) { dedicatedUsed = value.largeValue; } else { dedicatedUsed = 0; PdhRemoveCounter(counter); PdhCloseQuery(query); return false; } PdhRemoveCounter(counter); PdhCloseQuery(query); return true; }
2. 自追踪应用自身的显存占用
如果只需要统计当前应用的显存使用,可以在资源创建/销毁时手动记录:
- 创建纹理、顶点缓冲区、常量缓冲区等资源时,根据资源格式、大小计算占用的显存(注意考虑mipmap、内存对齐等因素)
- 释放资源时减去对应大小
- 这种方式完全可控,性能开销极低,但只能统计自身进程的显存使用,无法获取系统全局的显存状态
3. WMI查询(适合非实时场景)
通过WMI的Win32_VideoController类查询显存相关属性,比如CurrentVideoMemoryUsage:
- 优点是实现简单,不需要处理复杂的PDH API
- 缺点是更新频率较低(通常几秒一次),实时性不足,不适合需要高频获取的场景
内容的提问来源于stack exchange,提问作者Axel Rietschin
相关产品推荐
相关产品推荐

