diff --git a/src/detection/gpu/gpu_windows.c b/src/detection/gpu/gpu_windows.c index 23959106c..0c0699718 100644 --- a/src/detection/gpu/gpu_windows.c +++ b/src/detection/gpu/gpu_windows.c @@ -8,6 +8,7 @@ #include #include #include +#include "util/windows/nt.h" #define FF_EMPTY_GUID_STR L"{00000000-0000-0000-0000-000000000000}" 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* if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL) gpu->type = gpu->deviceId == 20 ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE; - uint64_t dedicatedVideoMemory = 0; - if(ffRegReadUint64(hDirectxKey, L"DedicatedVideoMemory", &dedicatedVideoMemory, NULL)) - { - if (gpu->type == FF_GPU_TYPE_UNKNOWN) - gpu->type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED; - } - - uint64_t dedicatedSystemMemory, sharedSystemMemory; - if(ffRegReadUint64(hDirectxKey, L"DedicatedSystemMemory", &dedicatedSystemMemory, NULL) && - ffRegReadUint64(hDirectxKey, L"SharedSystemMemory", &sharedSystemMemory, NULL)) - { - gpu->dedicated.total = dedicatedVideoMemory + dedicatedSystemMemory; - gpu->shared.total = sharedSystemMemory; - } + ffRegReadUint64(hDirectxKey, L"DedicatedVideoMemory", &gpu->dedicated.total, NULL); + ffRegReadUint64(hDirectxKey, L"DedicatedSystemMemory", &gpu->shared.total, NULL); if (ffRegReadUint64(hDirectxKey, L"AdapterLuid", &adapterLuid, NULL)) { @@ -135,6 +124,28 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* } } + if (adapterLuid > 0) + { + D3DKMT_OPENADAPTERFROMLUID openAdapterFromLuid = { .AdapterLuid = *(LUID*)&adapterLuid }; + if (NT_SUCCESS(D3DKMTOpenAdapterFromLuid(&openAdapterFromLuid))) + { + D3DKMT_ADAPTERTYPE adapterType = {}; + D3DKMT_QUERYADAPTERINFO queryAdapterInfo = { + .hAdapter = openAdapterFromLuid.hAdapter, + .Type = KMTQAITYPE_ADAPTERTYPE, + .pPrivateDriverData = &adapterType, + .PrivateDriverDataSize = sizeof(adapterType), + }; + if (NT_SUCCESS(D3DKMTQueryAdapterInfo(&queryAdapterInfo))) + { + if (adapterType.HybridDiscrete) + gpu->type = FF_GPU_TYPE_DISCRETE; + else if (adapterType.HybridIntegrated) + gpu->type = FF_GPU_TYPE_INTEGRATED; + } + } + } + if (gpu->vendor.length == 0) { bufferLen = sizeof(buffer); @@ -223,6 +234,8 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* if (CM_Get_DevNode_Registry_PropertyW(devInst, CM_DRP_DEVICEDESC, NULL, buffer, &bufferLen, 0) == CR_SUCCESS) ffStrbufSetWS(&gpu->name, buffer); } + if (gpu->type == FF_GPU_TYPE_UNKNOWN && gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET) + gpu->type = gpu->dedicated.total >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED; } return NULL; diff --git a/src/util/windows/nt.h b/src/util/windows/nt.h index 53b33169b..8976ccbac 100644 --- a/src/util/windows/nt.h +++ b/src/util/windows/nt.h @@ -23,3 +23,61 @@ NTSTATUS NTAPI NtPowerInformation( NTSTATUS NTAPI RtlGetVersion( _Inout_ PRTL_OSVERSIONINFOW lpVersionInformation ); + +#if __has_include() +#include +#else +typedef UINT D3DKMT_HANDLE; + +typedef struct _D3DKMT_OPENADAPTERFROMLUID +{ + LUID AdapterLuid; + D3DKMT_HANDLE hAdapter; +} D3DKMT_OPENADAPTERFROMLUID; +EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTOpenAdapterFromLuid(_Inout_ CONST D3DKMT_OPENADAPTERFROMLUID*); + +typedef struct _D3DKMT_CLOSEADAPTER +{ + D3DKMT_HANDLE hAdapter; // in: adapter handle +} D3DKMT_CLOSEADAPTER; +EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTCloseAdapter(_In_ CONST D3DKMT_CLOSEADAPTER*); + +typedef struct _D3DKMT_ADAPTERTYPE +{ + union + { + struct + { + UINT RenderSupported : 1; + UINT DisplaySupported : 1; + UINT SoftwareDevice : 1; + UINT PostDevice : 1; + UINT HybridDiscrete : 1; + UINT HybridIntegrated : 1; + UINT IndirectDisplayDevice : 1; + UINT Paravirtualized : 1; + UINT ACGSupported : 1; + UINT SupportSetTimingsFromVidPn : 1; + UINT Detachable : 1; + UINT ComputeOnly : 1; + UINT Prototype : 1; + UINT RuntimePowerManagement : 1; + UINT Reserved : 18; + }; + UINT Value; + }; +} D3DKMT_ADAPTERTYPE; + +typedef enum _KMTQUERYADAPTERINFOTYPE +{ + KMTQAITYPE_ADAPTERTYPE = 15, +} KMTQUERYADAPTERINFOTYPE; +typedef struct _D3DKMT_QUERYADAPTERINFO +{ + D3DKMT_HANDLE hAdapter; + KMTQUERYADAPTERINFOTYPE Type; + VOID* pPrivateDriverData; + UINT PrivateDriverDataSize; +} D3DKMT_QUERYADAPTERINFO; +EXTERN_C _Check_return_ NTSTATUS APIENTRY D3DKMTQueryAdapterInfo(_Inout_ CONST D3DKMT_QUERYADAPTERINFO*); +#endif