您需要调用一些未记录的 direct3d API 函数 D3DKMTQueryStatistics。
取自ProcessHacker 论坛的示例代码:
#define _Field_size_(...)
#define _Field_size_bytes_(...)
#define _In_reads_bytes_opt_(...)
#define _Out_writes_bytes_all_opt_(...)
#define _Field_size_bytes_part_(...)
#define _In_range_(...)
#define _Out_writes_bytes_(...)
#define _Check_return_
#define _Inout_
#define _In_
#define _Out_
#define NTDDI_VERSION NTDDI_WIN7
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include "d3dkmthk.h"
#pragma comment(lib, "gdi32.lib") // Doesn't do much, since it doesn't have the exports anyway...
#pragma comment(lib, "advapi32.lib")
typedef NTSTATUS (APIENTRY *PD3DKMTQueryStatistics)(_In_ CONST D3DKMT_QUERYSTATISTICS*);
typedef NTSTATUS (APIENTRY *PD3DKMTOpenAdapterFromDeviceName)(_Inout_ D3DKMT_OPENADAPTERFROMDEVICENAME*);
int _tmain(int argc, TCHAR *argv[])
{
LUID luid = { 20 };
TOKEN_PRIVILEGES privs = { 1, { luid, SE_PRIVILEGE_ENABLED } };
HANDLE hToken;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
if (AdjustTokenPrivileges(hToken, FALSE, &privs, sizeof(privs), NULL, NULL))
{
}
else { return -1; }
}
else { return -2; }
D3DKMT_OPENADAPTERFROMDEVICENAME name = { _T("\\\\?\\pci#ven_10de&dev_0a2b&subsys_9072104d&rev_a2#4&12796cb&0&0008#{1ca05180-a699-450a-9a0c-de4fbe3ddd89}") };
HMODULE hGdi32 = LoadLibrary(_T("gdi32.dll"));
PD3DKMTOpenAdapterFromDeviceName D3DKMTOpenAdapterFromDeviceName = (PD3DKMTOpenAdapterFromDeviceName)GetProcAddress(hGdi32, "D3DKMTOpenAdapterFromDeviceName");
NTSTATUS status = D3DKMTOpenAdapterFromDeviceName(&name);
if (status == 0)
{
_tprintf(_T("name.AdapterLuid: %llx\n"), name.AdapterLuid);
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, GetCurrentProcessId());
_tprintf(_T("hProcess: %#p\n"), hProcess);
if (hProcess != NULL)
{
for (;;)
{
PD3DKMTQueryStatistics D3DKMTQueryStatistics = (PD3DKMTQueryStatistics)GetProcAddress(hGdi32, "D3DKMTQueryStatistics");
D3DKMT_QUERYSTATISTICS stats = { D3DKMT_QUERYSTATISTICS_PROCESS, name.AdapterLuid, hProcess };
status = D3DKMTQueryStatistics(&stats);
if (status == 0)
{
_tprintf(_T("Usage: %#llx\n"), stats.QueryResult.ProcessInformation.SystemMemory.BytesAllocated);
}
else { break; }
fflush(stdout);
Sleep(1000);
}
}
}
_tprintf(_T("%#x\n"), status);
return status;
}
更多对 D3DKMTQueryStatistics 的调用可以从 gpumon.c 代码中采样。