3535 * does not have a registered VA driver
3636*/
3737const char VAAPI_DEFAULT_DRIVER_NAME [] = "vaon12" ;
38- const char VAAPI_REG_SUB_KEY [] = "VAAPIDriverName" ;
39- const char VAAPI_REG_SUB_KEY_WOW [] = "VAAPIDriverNameWow" ;
40-
41- inline const char * GetVAAPIRegKeyName ()
42- {
43- #ifdef _WIN64
44- return VAAPI_REG_SUB_KEY ;
45- #else
46- BOOL is_wow64 = FALSE;
47- if (IsWow64Process (GetCurrentProcess (), & is_wow64 ) && is_wow64 )
48- return VAAPI_REG_SUB_KEY_WOW ;
49- return VAAPI_REG_SUB_KEY ;
50- #endif
51- }
5238
5339typedef struct _VADisplayContextWin32 {
5440 LUID adapter_luid ;
@@ -58,136 +44,73 @@ typedef struct _VADisplayContextWin32 {
5844
5945static bool TryLoadDriverNameFromRegistry (const LUID * adapter_luid , VADisplayContextWin32 * pWin32Ctx )
6046{
61- if (!adapter_luid )
62- return false;
63-
64- /* Get handle to GDI Runtime */
65- HMODULE h = LoadLibrary ("gdi32.dll" );
66- if (h == NULL )
47+ HMODULE hGdi32 = LoadLibraryA ("gdi32.dll" );
48+ if (!hGdi32 )
6749 return false;
6850
51+ D3DKMT_OPENADAPTERFROMLUID OpenArgs = { .AdapterLuid = * adapter_luid };
52+ D3DDDI_QUERYREGISTRY_INFO RegistryInfo = {
53+ .QueryType = D3DDDI_QUERYREGISTRY_ADAPTERKEY ,
54+ .QueryFlags .TranslatePath = true,
55+ .ValueName = L"VAAPIDriverName" ,
56+ .ValueType = REG_SZ ,
57+ };
58+ D3DDDI_QUERYREGISTRY_INFO * pRegistryInfo = & RegistryInfo ;
59+ #ifndef _WIN64
60+ BOOL isWowProcess = false;
61+ if (IsWow64Process (GetCurrentProcess (), & isWowProcess ) && isWowProcess )
62+ wcscpy (RegistryInfo .ValueName , "VAAPIDriverNameWow" );
63+ #endif
64+ D3DKMT_QUERYADAPTERINFO QAI = {
65+ .Type = KMTQAITYPE_QUERYREGISTRY ,
66+ .pPrivateDriverData = & RegistryInfo ,
67+ .PrivateDriverDataSize = sizeof (RegistryInfo ),
68+ };
6969 bool ret = false;
70- int result = 0 ;
71- /* Check the OS version */
72- if (GetProcAddress (h , "D3DKMTSubmitPresentBltToHwQueue" )) {
73- D3DKMT_ENUMADAPTERS2 EnumAdapters ;
74- NTSTATUS status = STATUS_SUCCESS ;
7570
76- EnumAdapters .NumAdapters = 0 ;
77- EnumAdapters .pAdapters = NULL ;
78- PFND3DKMT_ENUMADAPTERS2 pEnumAdapters2 = (PFND3DKMT_ENUMADAPTERS2 )GetProcAddress (h , "D3DKMTEnumAdapters2" );
79- if (!pEnumAdapters2 ) {
80- fprintf (stderr , "VA_Win32: GetProcAddress failed for D3DKMTEnumAdapters2\n" );
81- goto out ;
82- }
83- PFND3DKMT_QUERYADAPTERINFO pQueryAdapterInfo = (PFND3DKMT_QUERYADAPTERINFO )GetProcAddress (h , "D3DKMTQueryAdapterInfo" );
84- if (!pQueryAdapterInfo ) {
85- fprintf (stderr , "VA_Win32: GetProcAddress failed for D3DKMTQueryAdapterInfo\n" );
86- goto out ;
87- }
88- while (1 ) {
89- EnumAdapters .NumAdapters = 0 ;
90- EnumAdapters .pAdapters = NULL ;
91- status = pEnumAdapters2 (& EnumAdapters );
92- if (status == STATUS_BUFFER_TOO_SMALL ) {
93- /* Number of Adapters increased between calls, retry; */
94- continue ;
95- } else if (!NT_SUCCESS (status )) {
96- fprintf (stderr , "VA_Win32: D3DKMTEnumAdapters2 status != SUCCESS\n" );
97- goto out ;
98- }
99- break ;
100- }
101- EnumAdapters .pAdapters = malloc (sizeof (* EnumAdapters .pAdapters ) * (EnumAdapters .NumAdapters ));
102- if (EnumAdapters .pAdapters == NULL ) {
103- fprintf (stderr , "VA_Win32: Allocation failure for adapters buffer\n" );
104- goto out ;
105- }
106- status = pEnumAdapters2 (& EnumAdapters );
107- if (!NT_SUCCESS (status )) {
108- fprintf (stderr , "VA_Win32: D3DKMTEnumAdapters2 status != SUCCESS\n" );
109- goto out ;
110- }
111- const char * cszVAAPIRegKeyName = GetVAAPIRegKeyName ();
112- const int szVAAPIRegKeyName = (int )(strlen (cszVAAPIRegKeyName ) + 1 ) * sizeof (cszVAAPIRegKeyName [0 ]);
113- for (UINT AdapterIndex = 0 ; AdapterIndex < EnumAdapters .NumAdapters ; AdapterIndex ++ ) {
114- D3DDDI_QUERYREGISTRY_INFO queryArgs = {0 };
115- D3DDDI_QUERYREGISTRY_INFO * pQueryArgs = & queryArgs ;
116- D3DDDI_QUERYREGISTRY_INFO * pQueryBuffer = NULL ;
117- queryArgs .QueryType = D3DDDI_QUERYREGISTRY_ADAPTERKEY ;
118- queryArgs .QueryFlags .TranslatePath = TRUE;
119- queryArgs .ValueType = REG_SZ ;
120- result = MultiByteToWideChar (
121- CP_ACP ,
122- 0 ,
123- cszVAAPIRegKeyName ,
124- szVAAPIRegKeyName ,
125- queryArgs .ValueName ,
126- ARRAYSIZE (queryArgs .ValueName ));
127- if (!result ) {
128- fprintf (stderr , "VA_Win32: MultiByteToWideChar status != SUCCESS\n" );
129- continue ;
130- }
131- D3DKMT_QUERYADAPTERINFO queryAdapterInfo = {0 };
132- queryAdapterInfo .hAdapter = EnumAdapters .pAdapters [AdapterIndex ].hAdapter ;
133- queryAdapterInfo .Type = KMTQAITYPE_QUERYREGISTRY ;
134- queryAdapterInfo .pPrivateDriverData = & queryArgs ;
135- queryAdapterInfo .PrivateDriverDataSize = sizeof (queryArgs );
136- status = pQueryAdapterInfo (& queryAdapterInfo );
137- if (!NT_SUCCESS (status )) {
138- /* Try a different value type. Some vendors write the key as a multi-string type. */
139- queryArgs .ValueType = REG_MULTI_SZ ;
140- status = pQueryAdapterInfo (& queryAdapterInfo );
141- if (NT_SUCCESS (status )) {
142- fprintf (stderr , "VA_Win32: Accepting multi-string registry key type\n" );
143- } else {
144- /* Continue trying to get as much info on each adapter as possible. */
145- /* It's too late to return FALSE and claim WDDM2_4 enumeration is not available here. */
146- continue ;
147- }
148- }
149- if (NT_SUCCESS (status ) && pQueryArgs -> Status == D3DDDI_QUERYREGISTRY_STATUS_BUFFER_OVERFLOW ) {
150- ULONG queryBufferSize = sizeof (D3DDDI_QUERYREGISTRY_INFO ) + queryArgs .OutputValueSize ;
151- pQueryBuffer = malloc (queryBufferSize );
152- if (pQueryBuffer == NULL )
153- continue ;
154- memcpy (pQueryBuffer , & queryArgs , sizeof (D3DDDI_QUERYREGISTRY_INFO ));
155- queryAdapterInfo .pPrivateDriverData = pQueryBuffer ;
156- queryAdapterInfo .PrivateDriverDataSize = queryBufferSize ;
157- status = pQueryAdapterInfo (& queryAdapterInfo );
158- pQueryArgs = pQueryBuffer ;
159- }
160- if (NT_SUCCESS (status ) && pQueryArgs -> Status == D3DDDI_QUERYREGISTRY_STATUS_SUCCESS ) {
161- wchar_t * pWchar = pQueryArgs -> OutputString ;
162- memset (pWin32Ctx -> registry_driver_name , 0 , sizeof (pWin32Ctx -> registry_driver_name ));
163- size_t len ;
164- wcstombs_s (& len , pWin32Ctx -> registry_driver_name , sizeof (pWin32Ctx -> registry_driver_name ), pWchar , sizeof (pWin32Ctx -> registry_driver_name ));
165- assert (len <= (sizeof (pWin32Ctx -> registry_driver_name ) - 1 ));
166- if (0 == memcmp (adapter_luid , & EnumAdapters .pAdapters [AdapterIndex ].AdapterLuid , sizeof (EnumAdapters .pAdapters [AdapterIndex ].AdapterLuid ))) {
167- ret = true;
168- /* Found the adapter we wanted, finish iteration. Associated driver string is loaded in pWin32Ctx->registry_driver_name */
169- /* VAAPI needs the stripped driver filename, without the absolute path or the extension. */
170-
171- /* Zero-out the extension section with null terminators if present */
172- char * pExtPosition = strstr (pWin32Ctx -> registry_driver_name , ".dll" );
173- if (pExtPosition )
174- memset (pExtPosition , '\0' , 4 /*size of the 4 chars of .dll*/ );
175-
176- free (pQueryBuffer );
177- goto out ;
178- }
179- } else if (status == (NTSTATUS )STATUS_INVALID_PARAMETER ) {
180- free (pQueryBuffer );
181- goto out ;
182- }
183- free (pQueryBuffer );
184- }
185- out :
186- free (EnumAdapters .pAdapters );
71+ PFND3DKMT_OPENADAPTERFROMLUID pfnOpenAdapterFromLuid = (PFND3DKMT_OPENADAPTERFROMLUID )GetProcAddress (hGdi32 , "D3DKMTOpenAdapterFromLuid" );
72+ PFND3DKMT_CLOSEADAPTER pfnCloseAdapter = (PFND3DKMT_CLOSEADAPTER )GetProcAddress (hGdi32 , "D3DKMTCloseAdapter" );
73+ PFND3DKMT_QUERYADAPTERINFO pfnQueryAdapterInfo = (PFND3DKMT_QUERYADAPTERINFO )GetProcAddress (hGdi32 , "D3DKMTQueryAdapterInfo" );
74+ if (!pfnOpenAdapterFromLuid || !pfnCloseAdapter || !pfnQueryAdapterInfo )
75+ goto cleanup ;
76+
77+ if (!NT_SUCCESS (pfnOpenAdapterFromLuid (& OpenArgs )))
78+ goto cleanup ;
79+
80+ QAI .hAdapter = OpenArgs .hAdapter ;
81+ if (!NT_SUCCESS (pfnQueryAdapterInfo (& QAI )) ||
82+ pRegistryInfo -> Status != D3DDDI_QUERYREGISTRY_STATUS_BUFFER_OVERFLOW )
83+ goto cleanup ;
84+
85+ size_t RegistryInfoSize = sizeof (RegistryInfo ) + RegistryInfo .OutputValueSize ;
86+ pRegistryInfo = malloc (RegistryInfoSize );
87+ if (!pRegistryInfo )
88+ goto cleanup ;
89+
90+ memcpy (pRegistryInfo , & RegistryInfo , sizeof (RegistryInfo ));
91+ QAI .pPrivateDriverData = pRegistryInfo ;
92+ QAI .PrivateDriverDataSize = RegistryInfoSize ;
93+ if (!NT_SUCCESS (pfnQueryAdapterInfo (& QAI )) ||
94+ pRegistryInfo -> Status != D3DDDI_QUERYREGISTRY_STATUS_SUCCESS )
95+ goto cleanup ;
96+
97+ if (!WideCharToMultiByte (CP_ACP , 0 , pRegistryInfo -> OutputString ,
98+ RegistryInfo .OutputValueSize / sizeof (wchar_t ),
99+ pWin32Ctx -> registry_driver_name ,
100+ sizeof (pWin32Ctx -> registry_driver_name ),
101+ NULL , NULL ))
102+ goto cleanup ;
103+
104+ ret = true;
105+
106+ cleanup :
107+ if (pRegistryInfo && pRegistryInfo != & RegistryInfo )
108+ free (pRegistryInfo );
109+ if (pfnCloseAdapter && OpenArgs .hAdapter ) {
110+ D3DKMT_CLOSEADAPTER Close = { OpenArgs .hAdapter };
111+ pfnCloseAdapter (& Close );
187112 }
188-
189- FreeLibrary (h );
190-
113+ FreeLibrary (hGdi32 );
191114 return ret ;
192115}
193116
0 commit comments