@@ -17,6 +17,11 @@ static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev)
1717#define FF_EMPTY_GUID_STR L"{00000000-0000-0000-0000-000000000000}"
1818enum { FF_GUID_STRLEN = sizeof (FF_EMPTY_GUID_STR ) / sizeof (wchar_t ) - 1 };
1919
20+ wchar_t regDirectxKey [] = L"SOFTWARE\\Microsoft\\DirectX\\" FF_EMPTY_GUID_STR ;
21+ const uint32_t regDirectxKeyPrefixLength = (uint32_t ) __builtin_strlen ("SOFTWARE\\Microsoft\\DirectX\\" );
22+ wchar_t regDriverKey [] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\" FF_EMPTY_GUID_STR L"\\0000" ;
23+ const uint32_t regDriverKeyPrefixLength = (uint32_t ) __builtin_strlen ("SYSTEM\\CurrentControlSet\\Control\\Class\\" );
24+
2025const char * ffDetectGPUImpl (FF_MAYBE_UNUSED const FFGPUOptions * options , FFlist * gpus )
2126{
2227 HDEVINFO hdev __attribute__((__cleanup__ (wrapSetupDiDestroyDeviceInfoList ))) =
@@ -25,11 +30,6 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
2530 if (hdev == INVALID_HANDLE_VALUE )
2631 return "SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY) failed" ;
2732
28- wchar_t regDirectxKey [] = L"SOFTWARE\\Microsoft\\DirectX\\" FF_EMPTY_GUID_STR ;
29- const uint32_t regDirectxKeyPrefixLength = (uint32_t ) strlen ("SOFTWARE\\Microsoft\\DirectX\\" );
30- wchar_t regControlVideoKey [] = L"SYSTEM\\CurrentControlSet\\Control\\Video\\" FF_EMPTY_GUID_STR L"\\0000" ;
31- const uint32_t regControlVideoKeyPrefixLength = (uint32_t ) strlen ("SYSTEM\\CurrentControlSet\\Control\\Video\\" );
32-
3333 SP_DEVINFO_DATA did = { .cbSize = sizeof (did ) };
3434 for (DWORD idev = 0 ; SetupDiEnumDeviceInfo (hdev , idev , & did ); ++ idev )
3535 {
@@ -50,74 +50,87 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
5050 if (SetupDiGetDeviceRegistryPropertyW (hdev , & did , SPDRP_DEVICEDESC , NULL , (PBYTE ) buffer , sizeof (buffer ), NULL ))
5151 ffStrbufSetWS (& gpu -> name , buffer );
5252
53- if (!SetupDiGetDeviceRegistryPropertyW (hdev , & did , SPDRP_HARDWAREID , NULL , (PBYTE ) buffer , sizeof (buffer ), NULL ))
54- continue ;
55-
56- unsigned vendorId = 0 , deviceId = 0 , subSystemId = 0 , revId = 0 ;
57- swscanf (buffer , L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x&REV_%x" , & vendorId , & deviceId , & subSystemId , & revId );
58- ffStrbufSetStatic (& gpu -> vendor , ffGetGPUVendorString (vendorId ));
59-
6053 FF_HKEY_AUTO_DESTROY hVideoIdKey = SetupDiOpenDevRegKey (hdev , & did , DICS_FLAG_GLOBAL , 0 , DIREG_DEV , KEY_QUERY_VALUE );
6154 if (!hVideoIdKey ) continue ;
62- DWORD videoIdLength = sizeof (buffer );
63- if (RegGetValueW (hVideoIdKey , NULL , L"VideoID" , RRF_RT_REG_SZ , NULL , buffer , & videoIdLength ) != ERROR_SUCCESS )
64- continue ;
65-
66- if (videoIdLength != (FF_GUID_STRLEN + 1 ) * sizeof (wchar_t ))
67- continue ; // Should not happen
68-
69- wmemcpy (regControlVideoKey + regControlVideoKeyPrefixLength , buffer , FF_GUID_STRLEN );
70- FF_HKEY_AUTO_DESTROY hRegControlVideoKey = NULL ;
71- if (!ffRegOpenKeyForRead (HKEY_LOCAL_MACHINE , regControlVideoKey , & hRegControlVideoKey , NULL )) continue ;
72-
73- wmemcpy (regDirectxKey + regDirectxKeyPrefixLength , buffer , FF_GUID_STRLEN );
74- FF_HKEY_AUTO_DESTROY hDirectxKey = NULL ;
75- if (ffRegOpenKeyForRead (HKEY_LOCAL_MACHINE , regDirectxKey , & hDirectxKey , NULL ))
55+ DWORD bufferLen = sizeof (buffer );
56+ if (RegGetValueW (hVideoIdKey , NULL , L"VideoID" , RRF_RT_REG_SZ , NULL , buffer , & bufferLen ) == ERROR_SUCCESS &&
57+ bufferLen == (FF_GUID_STRLEN + 1 ) * sizeof (wchar_t ))
7658 {
77- uint64_t dedicatedVideoMemory = 0 ;
78- if (ffRegReadUint64 (hDirectxKey , L"DedicatedVideoMemory" , & dedicatedVideoMemory , NULL ))
79- gpu -> type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED ;
80-
81- uint64_t dedicatedSystemMemory , sharedSystemMemory ;
82- if (ffRegReadUint64 (hDirectxKey , L"DedicatedSystemMemory" , & dedicatedSystemMemory , NULL ) &&
83- ffRegReadUint64 (hDirectxKey , L"SharedSystemMemory" , & sharedSystemMemory , NULL ))
59+ wmemcpy (regDirectxKey + regDirectxKeyPrefixLength , buffer , FF_GUID_STRLEN );
60+ FF_HKEY_AUTO_DESTROY hDirectxKey = NULL ;
61+ if (ffRegOpenKeyForRead (HKEY_LOCAL_MACHINE , regDirectxKey , & hDirectxKey , NULL ))
8462 {
85- gpu -> dedicated .total = dedicatedVideoMemory + dedicatedSystemMemory ;
86- gpu -> shared .total = sharedSystemMemory ;
63+ uint64_t dedicatedVideoMemory = 0 ;
64+ if (ffRegReadUint64 (hDirectxKey , L"DedicatedVideoMemory" , & dedicatedVideoMemory , NULL ))
65+ gpu -> type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED ;
66+
67+ uint64_t dedicatedSystemMemory , sharedSystemMemory ;
68+ if (ffRegReadUint64 (hDirectxKey , L"DedicatedSystemMemory" , & dedicatedSystemMemory , NULL ) &&
69+ ffRegReadUint64 (hDirectxKey , L"SharedSystemMemory" , & sharedSystemMemory , NULL ))
70+ {
71+ gpu -> dedicated .total = dedicatedVideoMemory + dedicatedSystemMemory ;
72+ gpu -> shared .total = sharedSystemMemory ;
73+ }
74+
75+ ffRegReadUint64 (hDirectxKey , L"AdapterLuid" , & gpu -> deviceId , NULL );
76+
77+ uint32_t featureLevel = 0 ;
78+ if (ffRegReadUint (hDirectxKey , L"MaxD3D12FeatureLevel" , & featureLevel , NULL ) && featureLevel )
79+ ffStrbufSetF (& gpu -> platformApi , "Direct3D 12.%u" , (featureLevel & 0x0F00 ) >> 8 );
80+ else if (ffRegReadUint (hDirectxKey , L"MaxD3D11FeatureLevel" , & featureLevel , NULL ) && featureLevel )
81+ ffStrbufSetF (& gpu -> platformApi , "Direct3D 11.%u" , (featureLevel & 0x0F00 ) >> 8 );
82+
83+ uint64_t driverVersion = 0 ;
84+ if (ffRegReadUint64 (hDirectxKey , L"DriverVersion" , & driverVersion , NULL ) && driverVersion )
85+ {
86+ ffStrbufSetF (& gpu -> driver , "%u.%u.%u.%u" ,
87+ (unsigned ) (driverVersion >> 48 ) & 0xFFFF ,
88+ (unsigned ) (driverVersion >> 32 ) & 0xFFFF ,
89+ (unsigned ) (driverVersion >> 16 ) & 0xFFFF ,
90+ (unsigned ) (driverVersion >> 0 ) & 0xFFFF
91+ );
92+ }
93+
94+ uint32_t vendorId = 0 ;
95+ if (ffRegReadUint (hDirectxKey , L"VendorId" , & vendorId , NULL ) && vendorId )
96+ ffStrbufSetStatic (& gpu -> vendor , ffGetGPUVendorString (vendorId ));
8797 }
88-
89- ffRegReadUint64 (hDirectxKey , L"AdapterLuid" , & gpu -> deviceId , NULL );
90-
91- uint32_t featureLevel = 0 ;
92- if (ffRegReadUint (hDirectxKey , L"MaxD3D12FeatureLevel" , & featureLevel , NULL ) && featureLevel )
93- ffStrbufSetF (& gpu -> platformApi , "Direct3D 12.%u" , (featureLevel & 0x0F00 ) >> 8 );
94- else if (ffRegReadUint (hDirectxKey , L"MaxD3D11FeatureLevel" , & featureLevel , NULL ) && featureLevel )
95- ffStrbufSetF (& gpu -> platformApi , "Direct3D 11.%u" , (featureLevel & 0x0F00 ) >> 8 );
96- }
97- else if (!ffRegReadUint64 (hRegControlVideoKey , L"HardwareInformation.qwMemorySize" , & gpu -> dedicated .total , NULL ))
98- {
99- uint32_t vmem = 0 ;
100- if (ffRegReadUint (hRegControlVideoKey , L"HardwareInformation.MemorySize" , & vmem , NULL ))
101- gpu -> dedicated .total = vmem ;
102- gpu -> type = gpu -> dedicated .total > 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED ;
10398 }
10499
105100 if (gpu -> vendor .length == 0 )
106101 {
107- ffRegReadStrbuf (hRegControlVideoKey , L"ProviderName" , & gpu -> vendor , NULL );
108- if (ffStrbufContainS (& gpu -> vendor , "Intel" ))
109- ffStrbufSetStatic (& gpu -> vendor , FF_GPU_VENDOR_NAME_INTEL );
110- else if (ffStrbufContainS (& gpu -> vendor , "NVIDIA" ))
111- ffStrbufSetStatic (& gpu -> vendor , FF_GPU_VENDOR_NAME_NVIDIA );
112- else if (ffStrbufContainS (& gpu -> vendor , "AMD" ) || ffStrbufContainS (& gpu -> vendor , "ATI" ))
113- ffStrbufSetStatic (& gpu -> vendor , FF_GPU_VENDOR_NAME_AMD );
102+ bufferLen = sizeof (buffer );
103+ if (SetupDiGetDeviceRegistryPropertyW (hdev , & did , SPDRP_DRIVER , NULL , (PBYTE ) buffer , sizeof (buffer ), & bufferLen ) && bufferLen == (FF_GUID_STRLEN + strlen ("\\0000" ) + 1 ) * 2 )
104+ {
105+ wmemcpy (regDriverKey + regDriverKeyPrefixLength , buffer , FF_GUID_STRLEN + strlen ("\\0000" ));
106+ FF_HKEY_AUTO_DESTROY hRegDriverKey = NULL ;
107+ if (ffRegOpenKeyForRead (HKEY_LOCAL_MACHINE , regDriverKey , & hRegDriverKey , NULL ))
108+ {
109+ if (ffRegReadStrbuf (hRegDriverKey , L"ProviderName" , & gpu -> vendor , NULL ))
110+ {
111+ if (ffStrbufContainS (& gpu -> vendor , "Intel" ))
112+ ffStrbufSetStatic (& gpu -> vendor , FF_GPU_VENDOR_NAME_INTEL );
113+ else if (ffStrbufContainS (& gpu -> vendor , "NVIDIA" ))
114+ ffStrbufSetStatic (& gpu -> vendor , FF_GPU_VENDOR_NAME_NVIDIA );
115+ else if (ffStrbufContainS (& gpu -> vendor , "AMD" ) || ffStrbufContainS (& gpu -> vendor , "ATI" ))
116+ ffStrbufSetStatic (& gpu -> vendor , FF_GPU_VENDOR_NAME_AMD );
117+ }
118+ }
119+ }
114120 }
115121
116122 __typeof__ (& ffDetectNvidiaGpuInfo ) detectFn ;
117123 const char * dllName ;
118124
119125 if (getDriverSpecificDetectionFn (gpu -> vendor .chars , & detectFn , & dllName ) && (options -> temp || options -> driverSpecific ))
120126 {
127+ unsigned vendorId = 0 , deviceId = 0 , subSystemId = 0 , revId = 0 ;
128+ if (SetupDiGetDeviceRegistryPropertyW (hdev , & did , SPDRP_HARDWAREID , NULL , (PBYTE ) buffer , sizeof (buffer ), NULL ))
129+ {
130+ swscanf (buffer , L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x&REV_%x" , & vendorId , & deviceId , & subSystemId , & revId );
131+ ffStrbufSetStatic (& gpu -> vendor , ffGetGPUVendorString (vendorId ));
132+ }
133+
121134 uint32_t pciBus , pciAddr ;
122135 if (SetupDiGetDeviceRegistryPropertyW (hdev , & did , SPDRP_BUSNUMBER , NULL , (PBYTE ) & pciBus , sizeof (pciBus ), NULL ) &&
123136 SetupDiGetDeviceRegistryPropertyW (hdev , & did , SPDRP_ADDRESS , NULL , (PBYTE ) & pciAddr , sizeof (pciAddr ), NULL ))
@@ -129,7 +142,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
129142 & (FFGpuDriverCondition ) {
130143 .type = FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID
131144 | (gpu -> deviceId > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_LUID : 0 )
132- | FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID ,
145+ | ( vendorId > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID : 0 ) ,
133146 .pciDeviceId = {
134147 .deviceId = deviceId ,
135148 .vendorId = vendorId ,
0 commit comments