如何使用C++微软API读取Dxdiag的VramInfo并解决DXGI取值不一致问题
读取Dxdiag VramInfo及DXGI结果不一致问题解决
1 DXGI与Dxdiag结果不一致的原因
你用DXGI的IDXGIAdapter::GetDesc()获取到的DedicatedVideoMemory值仅对应显卡独立的专用显存,而Dxdiag展示的显存总数值是专用显存+系统分配给GPU的共享内存的总和,二者统计口径不同自然会出现数值差异。如果仅用DXGI想要得到和Dxdiag一致的结果,把DedicatedVideoMemory和SharedSystemMemory两个字段的值相加即可。
2 直接读取Dxdiag官方VramInfo的C++实现
推荐直接调用微软官方的IDxDiagProvider COM接口,拿到的数值和Dxdiag工具展示的完全一致,实现代码如下:
#include <windows.h> #include <dxdiag.h> #pragma comment(lib, "dxguid.lib") HRESULT GetDxdiagVramInfo(UINT64& outTotalVram, WCHAR* outDisplayMemoryStr, UINT strBufSize) { HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (FAILED(hr)) return hr; IDxDiagProvider* pDxDiagProvider = nullptr; hr = CoCreateInstance(CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER, IID_IDxDiagProvider, (LPVOID*)&pDxDiagProvider); if (SUCCEEDED(hr)) { DXDIAG_INIT_PARAMS initParams = {}; initParams.dwSize = sizeof(DXDIAG_INIT_PARAMS); initParams.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION; initParams.bAllowWHQLChecks = FALSE; initParams.pReserved = NULL; hr = pDxDiagProvider->Initialize(&initParams); if (SUCCEEDED(hr)) { IDxDiagContainer* pRootContainer = nullptr; hr = pDxDiagProvider->GetRootContainer(&pRootContainer); if (SUCCEEDED(hr)) { IDxDiagContainer* pDisplayContainer = nullptr; // 取第一个显示设备,多显卡场景遍历nChild修改序号即可 hr = pRootContainer->GetChildContainer(L"DxDiag_DisplayDevices.0", &pDisplayContainer); if (SUCCEEDED(hr)) { VARIANT varVal; VariantInit(&varVal); // 取总显存数值 hr = pDisplayContainer->GetProp(L"DisplayMemory", &varVal); if (SUCCEEDED(hr)) { outTotalVram = varVal.ulVal * 1024ULL * 1024ULL; // 单位转换为字节 VariantClear(&varVal); } // 取szDisplayMemoryEnglish字段 hr = pDisplayContainer->GetProp(L"szDisplayMemoryEnglish", &varVal); if (SUCCEEDED(hr) && varVal.vt == VT_BSTR) { StringCchCopyW(outDisplayMemoryStr, strBufSize, varVal.bstrVal); VariantClear(&varVal); } pDisplayContainer->Release(); } pRootContainer->Release(); } } pDxDiagProvider->Release(); } CoUninitialize(); return hr; }
3 szDisplayMemoryEnglish字段用途
这个字段是Dxdiag容器内置的字符串属性,直接返回英文格式化完成的显存描述文本,内容和Dxdiag工具界面上英文版本展示的显存行完全一致,比如16384 MB NVIDIA GeForce RTX 4080。你不需要自行做字节到MB/GB的单位换算,也不需要处理显卡名称拼接,直接读取该字段就能拿到和Dxdiag展示完全相同的文本,专门给英文场景下需要直接复用Dxdiag显示内容的需求使用。
内容的提问来源于stack exchange,提问作者kunal pasricha
相关产品推荐
相关产品推荐

