Skip to content

Commit 61adc7c

Browse files
committed
GPU (Windows): new method to detect device type
1 parent 9ba30ad commit 61adc7c

2 files changed

Lines changed: 85 additions & 14 deletions

File tree

src/detection/gpu/gpu_windows.c

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <cfgmgr32.h>
99
#include <ntddvdeo.h>
1010
#include <devpkey.h>
11+
#include "util/windows/nt.h"
1112

1213
#define FF_EMPTY_GUID_STR L"{00000000-0000-0000-0000-000000000000}"
1314
enum { FF_GUID_STRLEN = sizeof(FF_EMPTY_GUID_STR) / sizeof(wchar_t) - 1 };
@@ -95,20 +96,8 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
9596
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
9697
gpu->type = gpu->deviceId == 20 ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
9798

98-
uint64_t dedicatedVideoMemory = 0;
99-
if(ffRegReadUint64(hDirectxKey, L"DedicatedVideoMemory", &dedicatedVideoMemory, NULL))
100-
{
101-
if (gpu->type == FF_GPU_TYPE_UNKNOWN)
102-
gpu->type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
103-
}
104-
105-
uint64_t dedicatedSystemMemory, sharedSystemMemory;
106-
if(ffRegReadUint64(hDirectxKey, L"DedicatedSystemMemory", &dedicatedSystemMemory, NULL) &&
107-
ffRegReadUint64(hDirectxKey, L"SharedSystemMemory", &sharedSystemMemory, NULL))
108-
{
109-
gpu->dedicated.total = dedicatedVideoMemory + dedicatedSystemMemory;
110-
gpu->shared.total = sharedSystemMemory;
111-
}
99+
ffRegReadUint64(hDirectxKey, L"DedicatedVideoMemory", &gpu->dedicated.total, NULL);
100+
ffRegReadUint64(hDirectxKey, L"DedicatedSystemMemory", &gpu->shared.total, NULL);
112101

113102
if (ffRegReadUint64(hDirectxKey, L"AdapterLuid", &adapterLuid, NULL))
114103
{
@@ -135,6 +124,28 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
135124
}
136125
}
137126

127+
if (adapterLuid > 0)
128+
{
129+
D3DKMT_OPENADAPTERFROMLUID openAdapterFromLuid = { .AdapterLuid = *(LUID*)&adapterLuid };
130+
if (NT_SUCCESS(D3DKMTOpenAdapterFromLuid(&openAdapterFromLuid)))
131+
{
132+
D3DKMT_ADAPTERTYPE adapterType = {};
133+
D3DKMT_QUERYADAPTERINFO queryAdapterInfo = {
134+
.hAdapter = openAdapterFromLuid.hAdapter,
135+
.Type = KMTQAITYPE_ADAPTERTYPE,
136+
.pPrivateDriverData = &adapterType,
137+
.PrivateDriverDataSize = sizeof(adapterType),
138+
};
139+
if (NT_SUCCESS(D3DKMTQueryAdapterInfo(&queryAdapterInfo)))
140+
{
141+
if (adapterType.HybridDiscrete)
142+
gpu->type = FF_GPU_TYPE_DISCRETE;
143+
else if (adapterType.HybridIntegrated)
144+
gpu->type = FF_GPU_TYPE_INTEGRATED;
145+
}
146+
}
147+
}
148+
138149
if (gpu->vendor.length == 0)
139150
{
140151
bufferLen = sizeof(buffer);
@@ -223,6 +234,8 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
223234
if (CM_Get_DevNode_Registry_PropertyW(devInst, CM_DRP_DEVICEDESC, NULL, buffer, &bufferLen, 0) == CR_SUCCESS)
224235
ffStrbufSetWS(&gpu->name, buffer);
225236
}
237+
if (gpu->type == FF_GPU_TYPE_UNKNOWN && gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET)
238+
gpu->type = gpu->dedicated.total >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
226239
}
227240

228241
return NULL;

src/util/windows/nt.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,61 @@ NTSTATUS NTAPI NtPowerInformation(
2323
NTSTATUS NTAPI RtlGetVersion(
2424
_Inout_ PRTL_OSVERSIONINFOW lpVersionInformation
2525
);
26+
27+
#if __has_include(<d3dkmthk.h>)
28+
#include <d3dkmthk.h>
29+
#else
30+
typedef UINT D3DKMT_HANDLE;
31+
32+
typedef struct _D3DKMT_OPENADAPTERFROMLUID
33+
{
34+
LUID AdapterLuid;
35+
D3DKMT_HANDLE hAdapter;
36+
} D3DKMT_OPENADAPTERFROMLUID;
37+
EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTOpenAdapterFromLuid(_Inout_ CONST D3DKMT_OPENADAPTERFROMLUID*);
38+
39+
typedef struct _D3DKMT_CLOSEADAPTER
40+
{
41+
D3DKMT_HANDLE hAdapter; // in: adapter handle
42+
} D3DKMT_CLOSEADAPTER;
43+
EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTCloseAdapter(_In_ CONST D3DKMT_CLOSEADAPTER*);
44+
45+
typedef struct _D3DKMT_ADAPTERTYPE
46+
{
47+
union
48+
{
49+
struct
50+
{
51+
UINT RenderSupported : 1;
52+
UINT DisplaySupported : 1;
53+
UINT SoftwareDevice : 1;
54+
UINT PostDevice : 1;
55+
UINT HybridDiscrete : 1;
56+
UINT HybridIntegrated : 1;
57+
UINT IndirectDisplayDevice : 1;
58+
UINT Paravirtualized : 1;
59+
UINT ACGSupported : 1;
60+
UINT SupportSetTimingsFromVidPn : 1;
61+
UINT Detachable : 1;
62+
UINT ComputeOnly : 1;
63+
UINT Prototype : 1;
64+
UINT RuntimePowerManagement : 1;
65+
UINT Reserved : 18;
66+
};
67+
UINT Value;
68+
};
69+
} D3DKMT_ADAPTERTYPE;
70+
71+
typedef enum _KMTQUERYADAPTERINFOTYPE
72+
{
73+
KMTQAITYPE_ADAPTERTYPE = 15,
74+
} KMTQUERYADAPTERINFOTYPE;
75+
typedef struct _D3DKMT_QUERYADAPTERINFO
76+
{
77+
D3DKMT_HANDLE hAdapter;
78+
KMTQUERYADAPTERINFOTYPE Type;
79+
VOID* pPrivateDriverData;
80+
UINT PrivateDriverDataSize;
81+
} D3DKMT_QUERYADAPTERINFO;
82+
EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTQueryAdapterInfo(_Inout_ CONST D3DKMT_QUERYADAPTERINFO*);
83+
#endif

0 commit comments

Comments
 (0)