xref: /aosp_15_r20/external/OpenCL-ICD-Loader/loader/windows/icd_windows.c (revision 1cddb830dba8aa7c1cc1039338e56b3b9fa24952)
1*1cddb830SAndroid Build Coastguard Worker /*
2*1cddb830SAndroid Build Coastguard Worker  * Copyright (c) 2016-2020 The Khronos Group Inc.
3*1cddb830SAndroid Build Coastguard Worker  *
4*1cddb830SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*1cddb830SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*1cddb830SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*1cddb830SAndroid Build Coastguard Worker  *
8*1cddb830SAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
9*1cddb830SAndroid Build Coastguard Worker  *
10*1cddb830SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*1cddb830SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*1cddb830SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*1cddb830SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*1cddb830SAndroid Build Coastguard Worker  * limitations under the License.
15*1cddb830SAndroid Build Coastguard Worker  *
16*1cddb830SAndroid Build Coastguard Worker  * OpenCL is a trademark of Apple Inc. used under license by Khronos.
17*1cddb830SAndroid Build Coastguard Worker  */
18*1cddb830SAndroid Build Coastguard Worker 
19*1cddb830SAndroid Build Coastguard Worker #include <initguid.h>
20*1cddb830SAndroid Build Coastguard Worker 
21*1cddb830SAndroid Build Coastguard Worker #include "icd.h"
22*1cddb830SAndroid Build Coastguard Worker #include "icd_windows.h"
23*1cddb830SAndroid Build Coastguard Worker #include "icd_windows_hkr.h"
24*1cddb830SAndroid Build Coastguard Worker #include "icd_windows_dxgk.h"
25*1cddb830SAndroid Build Coastguard Worker #include "icd_windows_apppackage.h"
26*1cddb830SAndroid Build Coastguard Worker #include <stdio.h>
27*1cddb830SAndroid Build Coastguard Worker #include <stdlib.h>
28*1cddb830SAndroid Build Coastguard Worker #include <windows.h>
29*1cddb830SAndroid Build Coastguard Worker #include <winreg.h>
30*1cddb830SAndroid Build Coastguard Worker 
31*1cddb830SAndroid Build Coastguard Worker #include <dxgi.h>
32*1cddb830SAndroid Build Coastguard Worker typedef HRESULT (WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID, void **);
33*1cddb830SAndroid Build Coastguard Worker 
34*1cddb830SAndroid Build Coastguard Worker static INIT_ONCE initialized = INIT_ONCE_STATIC_INIT;
35*1cddb830SAndroid Build Coastguard Worker 
36*1cddb830SAndroid Build Coastguard Worker typedef struct WinAdapter
37*1cddb830SAndroid Build Coastguard Worker {
38*1cddb830SAndroid Build Coastguard Worker     char * szName;
39*1cddb830SAndroid Build Coastguard Worker     LUID luid;
40*1cddb830SAndroid Build Coastguard Worker } WinAdapter;
41*1cddb830SAndroid Build Coastguard Worker 
42*1cddb830SAndroid Build Coastguard Worker const LUID ZeroLuid = { 0, 0 };
43*1cddb830SAndroid Build Coastguard Worker 
44*1cddb830SAndroid Build Coastguard Worker static WinAdapter* pWinAdapterBegin = NULL;
45*1cddb830SAndroid Build Coastguard Worker static WinAdapter* pWinAdapterEnd = NULL;
46*1cddb830SAndroid Build Coastguard Worker static WinAdapter* pWinAdapterCapacity = NULL;
47*1cddb830SAndroid Build Coastguard Worker 
adapterAdd(const char * szName,LUID luid)48*1cddb830SAndroid Build Coastguard Worker BOOL adapterAdd(const char* szName, LUID luid)
49*1cddb830SAndroid Build Coastguard Worker {
50*1cddb830SAndroid Build Coastguard Worker     BOOL result = TRUE;
51*1cddb830SAndroid Build Coastguard Worker     if (pWinAdapterEnd == pWinAdapterCapacity)
52*1cddb830SAndroid Build Coastguard Worker     {
53*1cddb830SAndroid Build Coastguard Worker         size_t oldCapacity = pWinAdapterCapacity - pWinAdapterBegin;
54*1cddb830SAndroid Build Coastguard Worker         size_t newCapacity = oldCapacity;
55*1cddb830SAndroid Build Coastguard Worker         if (0 == newCapacity)
56*1cddb830SAndroid Build Coastguard Worker         {
57*1cddb830SAndroid Build Coastguard Worker             newCapacity = 1;
58*1cddb830SAndroid Build Coastguard Worker         }
59*1cddb830SAndroid Build Coastguard Worker         else if(newCapacity < UINT_MAX/2)
60*1cddb830SAndroid Build Coastguard Worker         {
61*1cddb830SAndroid Build Coastguard Worker             newCapacity *= 2;
62*1cddb830SAndroid Build Coastguard Worker         }
63*1cddb830SAndroid Build Coastguard Worker 
64*1cddb830SAndroid Build Coastguard Worker         WinAdapter* pNewBegin = malloc(newCapacity * sizeof(*pWinAdapterBegin));
65*1cddb830SAndroid Build Coastguard Worker         if (!pNewBegin)
66*1cddb830SAndroid Build Coastguard Worker             result = FALSE;
67*1cddb830SAndroid Build Coastguard Worker         else
68*1cddb830SAndroid Build Coastguard Worker         {
69*1cddb830SAndroid Build Coastguard Worker             if (pWinAdapterBegin)
70*1cddb830SAndroid Build Coastguard Worker             {
71*1cddb830SAndroid Build Coastguard Worker                 memcpy(pNewBegin, pWinAdapterBegin, oldCapacity * sizeof(*pWinAdapterBegin));
72*1cddb830SAndroid Build Coastguard Worker                 free(pWinAdapterBegin);
73*1cddb830SAndroid Build Coastguard Worker             }
74*1cddb830SAndroid Build Coastguard Worker             pWinAdapterCapacity = pNewBegin + newCapacity;
75*1cddb830SAndroid Build Coastguard Worker             pWinAdapterEnd = pNewBegin + oldCapacity;
76*1cddb830SAndroid Build Coastguard Worker             pWinAdapterBegin = pNewBegin;
77*1cddb830SAndroid Build Coastguard Worker         }
78*1cddb830SAndroid Build Coastguard Worker     }
79*1cddb830SAndroid Build Coastguard Worker     if (pWinAdapterEnd != pWinAdapterCapacity)
80*1cddb830SAndroid Build Coastguard Worker     {
81*1cddb830SAndroid Build Coastguard Worker         size_t nameLen = (strlen(szName) + 1)*sizeof(szName[0]);
82*1cddb830SAndroid Build Coastguard Worker         pWinAdapterEnd->szName = malloc(nameLen);
83*1cddb830SAndroid Build Coastguard Worker         if (!pWinAdapterEnd->szName)
84*1cddb830SAndroid Build Coastguard Worker             result = FALSE;
85*1cddb830SAndroid Build Coastguard Worker         else
86*1cddb830SAndroid Build Coastguard Worker         {
87*1cddb830SAndroid Build Coastguard Worker             memcpy(pWinAdapterEnd->szName, szName, nameLen);
88*1cddb830SAndroid Build Coastguard Worker             pWinAdapterEnd->luid = luid;
89*1cddb830SAndroid Build Coastguard Worker             ++pWinAdapterEnd;
90*1cddb830SAndroid Build Coastguard Worker         }
91*1cddb830SAndroid Build Coastguard Worker     }
92*1cddb830SAndroid Build Coastguard Worker     return result;
93*1cddb830SAndroid Build Coastguard Worker }
94*1cddb830SAndroid Build Coastguard Worker 
adapterFree(WinAdapter * pWinAdapter)95*1cddb830SAndroid Build Coastguard Worker void adapterFree(WinAdapter *pWinAdapter)
96*1cddb830SAndroid Build Coastguard Worker {
97*1cddb830SAndroid Build Coastguard Worker     free(pWinAdapter->szName);
98*1cddb830SAndroid Build Coastguard Worker     pWinAdapter->szName = NULL;
99*1cddb830SAndroid Build Coastguard Worker }
100*1cddb830SAndroid Build Coastguard Worker 
101*1cddb830SAndroid Build Coastguard Worker #if defined(CL_ENABLE_LAYERS)
102*1cddb830SAndroid Build Coastguard Worker typedef struct WinLayer
103*1cddb830SAndroid Build Coastguard Worker {
104*1cddb830SAndroid Build Coastguard Worker     char * szName;
105*1cddb830SAndroid Build Coastguard Worker     DWORD priority;
106*1cddb830SAndroid Build Coastguard Worker } WinLayer;
107*1cddb830SAndroid Build Coastguard Worker 
108*1cddb830SAndroid Build Coastguard Worker static WinLayer* pWinLayerBegin;
109*1cddb830SAndroid Build Coastguard Worker static WinLayer* pWinLayerEnd;
110*1cddb830SAndroid Build Coastguard Worker static WinLayer* pWinLayerCapacity;
111*1cddb830SAndroid Build Coastguard Worker 
compareLayer(const void * a,const void * b)112*1cddb830SAndroid Build Coastguard Worker static int compareLayer(const void *a, const void *b)
113*1cddb830SAndroid Build Coastguard Worker {
114*1cddb830SAndroid Build Coastguard Worker     return ((WinLayer *)a)->priority < ((WinLayer *)b)->priority ? -1 :
115*1cddb830SAndroid Build Coastguard Worker            ((WinLayer *)a)->priority > ((WinLayer *)b)->priority ? 1 : 0;
116*1cddb830SAndroid Build Coastguard Worker }
117*1cddb830SAndroid Build Coastguard Worker 
layerAdd(const char * szName,DWORD priority)118*1cddb830SAndroid Build Coastguard Worker static BOOL layerAdd(const char* szName, DWORD priority)
119*1cddb830SAndroid Build Coastguard Worker {
120*1cddb830SAndroid Build Coastguard Worker     BOOL result = TRUE;
121*1cddb830SAndroid Build Coastguard Worker     if (pWinLayerEnd == pWinLayerCapacity)
122*1cddb830SAndroid Build Coastguard Worker     {
123*1cddb830SAndroid Build Coastguard Worker         size_t oldCapacity = pWinLayerCapacity - pWinLayerBegin;
124*1cddb830SAndroid Build Coastguard Worker         size_t newCapacity = oldCapacity;
125*1cddb830SAndroid Build Coastguard Worker         if (0 == newCapacity)
126*1cddb830SAndroid Build Coastguard Worker         {
127*1cddb830SAndroid Build Coastguard Worker             newCapacity = 1;
128*1cddb830SAndroid Build Coastguard Worker         }
129*1cddb830SAndroid Build Coastguard Worker         else if(newCapacity < UINT_MAX/2)
130*1cddb830SAndroid Build Coastguard Worker         {
131*1cddb830SAndroid Build Coastguard Worker             newCapacity *= 2;
132*1cddb830SAndroid Build Coastguard Worker         }
133*1cddb830SAndroid Build Coastguard Worker 
134*1cddb830SAndroid Build Coastguard Worker         WinLayer* pNewBegin = malloc(newCapacity * sizeof(*pWinLayerBegin));
135*1cddb830SAndroid Build Coastguard Worker         if (!pNewBegin)
136*1cddb830SAndroid Build Coastguard Worker         {
137*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("Failed allocate space for Layers array\n");
138*1cddb830SAndroid Build Coastguard Worker             result = FALSE;
139*1cddb830SAndroid Build Coastguard Worker         }
140*1cddb830SAndroid Build Coastguard Worker         else
141*1cddb830SAndroid Build Coastguard Worker         {
142*1cddb830SAndroid Build Coastguard Worker             if (pWinLayerBegin)
143*1cddb830SAndroid Build Coastguard Worker             {
144*1cddb830SAndroid Build Coastguard Worker                 memcpy(pNewBegin, pWinLayerBegin, oldCapacity * sizeof(*pWinLayerBegin));
145*1cddb830SAndroid Build Coastguard Worker                 free(pWinLayerBegin);
146*1cddb830SAndroid Build Coastguard Worker             }
147*1cddb830SAndroid Build Coastguard Worker             pWinLayerCapacity = pNewBegin + newCapacity;
148*1cddb830SAndroid Build Coastguard Worker             pWinLayerEnd = pNewBegin + oldCapacity;
149*1cddb830SAndroid Build Coastguard Worker             pWinLayerBegin = pNewBegin;
150*1cddb830SAndroid Build Coastguard Worker         }
151*1cddb830SAndroid Build Coastguard Worker     }
152*1cddb830SAndroid Build Coastguard Worker     if (pWinLayerEnd != pWinLayerCapacity)
153*1cddb830SAndroid Build Coastguard Worker     {
154*1cddb830SAndroid Build Coastguard Worker         size_t nameLen = (strlen(szName) + 1)*sizeof(szName[0]);
155*1cddb830SAndroid Build Coastguard Worker         pWinLayerEnd->szName = malloc(nameLen);
156*1cddb830SAndroid Build Coastguard Worker         if (!pWinLayerEnd->szName)
157*1cddb830SAndroid Build Coastguard Worker         {
158*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("Failed allocate space for Layer file path\n");
159*1cddb830SAndroid Build Coastguard Worker             result = FALSE;
160*1cddb830SAndroid Build Coastguard Worker         }
161*1cddb830SAndroid Build Coastguard Worker         else
162*1cddb830SAndroid Build Coastguard Worker         {
163*1cddb830SAndroid Build Coastguard Worker             memcpy(pWinLayerEnd->szName, szName, nameLen);
164*1cddb830SAndroid Build Coastguard Worker             pWinLayerEnd->priority = priority;
165*1cddb830SAndroid Build Coastguard Worker             ++pWinLayerEnd;
166*1cddb830SAndroid Build Coastguard Worker         }
167*1cddb830SAndroid Build Coastguard Worker     }
168*1cddb830SAndroid Build Coastguard Worker     return result;
169*1cddb830SAndroid Build Coastguard Worker }
170*1cddb830SAndroid Build Coastguard Worker 
layerFree(WinLayer * pWinLayer)171*1cddb830SAndroid Build Coastguard Worker void layerFree(WinLayer *pWinLayer)
172*1cddb830SAndroid Build Coastguard Worker {
173*1cddb830SAndroid Build Coastguard Worker     free(pWinLayer->szName);
174*1cddb830SAndroid Build Coastguard Worker     pWinLayer->szName = NULL;
175*1cddb830SAndroid Build Coastguard Worker }
176*1cddb830SAndroid Build Coastguard Worker #endif // defined(CL_ENABLE_LAYERS)
177*1cddb830SAndroid Build Coastguard Worker 
178*1cddb830SAndroid Build Coastguard Worker /*
179*1cddb830SAndroid Build Coastguard Worker  *
180*1cddb830SAndroid Build Coastguard Worker  * Vendor enumeration functions
181*1cddb830SAndroid Build Coastguard Worker  *
182*1cddb830SAndroid Build Coastguard Worker  */
183*1cddb830SAndroid Build Coastguard Worker 
184*1cddb830SAndroid Build Coastguard Worker // go through the list of vendors in the registry and call khrIcdVendorAdd
185*1cddb830SAndroid Build Coastguard Worker // for each vendor encountered
khrIcdOsVendorsEnumerate(PINIT_ONCE InitOnce,PVOID Parameter,PVOID * lpContext)186*1cddb830SAndroid Build Coastguard Worker BOOL CALLBACK khrIcdOsVendorsEnumerate(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *lpContext)
187*1cddb830SAndroid Build Coastguard Worker {
188*1cddb830SAndroid Build Coastguard Worker     LONG result;
189*1cddb830SAndroid Build Coastguard Worker     BOOL status = FALSE, currentStatus = FALSE;
190*1cddb830SAndroid Build Coastguard Worker     const char* platformsName = "SOFTWARE\\Khronos\\OpenCL\\Vendors";
191*1cddb830SAndroid Build Coastguard Worker     HKEY platformsKey = NULL;
192*1cddb830SAndroid Build Coastguard Worker     DWORD dwIndex;
193*1cddb830SAndroid Build Coastguard Worker 
194*1cddb830SAndroid Build Coastguard Worker     khrIcdInitializeTrace();
195*1cddb830SAndroid Build Coastguard Worker     khrIcdVendorsEnumerateEnv();
196*1cddb830SAndroid Build Coastguard Worker 
197*1cddb830SAndroid Build Coastguard Worker     currentStatus = khrIcdOsVendorsEnumerateDXGK();
198*1cddb830SAndroid Build Coastguard Worker     status |= currentStatus;
199*1cddb830SAndroid Build Coastguard Worker     if (!currentStatus)
200*1cddb830SAndroid Build Coastguard Worker     {
201*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("Failed to load via DXGK interface on RS4, continuing\n");
202*1cddb830SAndroid Build Coastguard Worker     }
203*1cddb830SAndroid Build Coastguard Worker 
204*1cddb830SAndroid Build Coastguard Worker     currentStatus = khrIcdOsVendorsEnumerateHKR();
205*1cddb830SAndroid Build Coastguard Worker     status |= currentStatus;
206*1cddb830SAndroid Build Coastguard Worker     if (!currentStatus)
207*1cddb830SAndroid Build Coastguard Worker     {
208*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("Failed to enumerate HKR entries, continuing\n");
209*1cddb830SAndroid Build Coastguard Worker     }
210*1cddb830SAndroid Build Coastguard Worker 
211*1cddb830SAndroid Build Coastguard Worker     currentStatus = khrIcdOsVendorsEnumerateAppPackage();
212*1cddb830SAndroid Build Coastguard Worker     status |= currentStatus;
213*1cddb830SAndroid Build Coastguard Worker     if (!currentStatus)
214*1cddb830SAndroid Build Coastguard Worker     {
215*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("Failed to enumerate App package entry, continuing\n");
216*1cddb830SAndroid Build Coastguard Worker     }
217*1cddb830SAndroid Build Coastguard Worker 
218*1cddb830SAndroid Build Coastguard Worker     KHR_ICD_TRACE("Opening key HKLM\\%s...\n", platformsName);
219*1cddb830SAndroid Build Coastguard Worker     result = RegOpenKeyExA(
220*1cddb830SAndroid Build Coastguard Worker         HKEY_LOCAL_MACHINE,
221*1cddb830SAndroid Build Coastguard Worker         platformsName,
222*1cddb830SAndroid Build Coastguard Worker         0,
223*1cddb830SAndroid Build Coastguard Worker         KEY_READ,
224*1cddb830SAndroid Build Coastguard Worker         &platformsKey);
225*1cddb830SAndroid Build Coastguard Worker     if (ERROR_SUCCESS != result)
226*1cddb830SAndroid Build Coastguard Worker     {
227*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("Failed to open platforms key %s, continuing\n", platformsName);
228*1cddb830SAndroid Build Coastguard Worker     }
229*1cddb830SAndroid Build Coastguard Worker     else
230*1cddb830SAndroid Build Coastguard Worker     {
231*1cddb830SAndroid Build Coastguard Worker         // for each value
232*1cddb830SAndroid Build Coastguard Worker         for (dwIndex = 0;; ++dwIndex)
233*1cddb830SAndroid Build Coastguard Worker         {
234*1cddb830SAndroid Build Coastguard Worker             char cszLibraryName[1024] = {0};
235*1cddb830SAndroid Build Coastguard Worker             DWORD dwLibraryNameSize = sizeof(cszLibraryName);
236*1cddb830SAndroid Build Coastguard Worker             DWORD dwLibraryNameType = 0;
237*1cddb830SAndroid Build Coastguard Worker             DWORD dwValue = 0;
238*1cddb830SAndroid Build Coastguard Worker             DWORD dwValueSize = sizeof(dwValue);
239*1cddb830SAndroid Build Coastguard Worker 
240*1cddb830SAndroid Build Coastguard Worker             // read the value name
241*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("Reading value %"PRIuDW"...\n", dwIndex);
242*1cddb830SAndroid Build Coastguard Worker             result = RegEnumValueA(
243*1cddb830SAndroid Build Coastguard Worker                   platformsKey,
244*1cddb830SAndroid Build Coastguard Worker                   dwIndex,
245*1cddb830SAndroid Build Coastguard Worker                   cszLibraryName,
246*1cddb830SAndroid Build Coastguard Worker                   &dwLibraryNameSize,
247*1cddb830SAndroid Build Coastguard Worker                   NULL,
248*1cddb830SAndroid Build Coastguard Worker                   &dwLibraryNameType,
249*1cddb830SAndroid Build Coastguard Worker                   (LPBYTE)&dwValue,
250*1cddb830SAndroid Build Coastguard Worker                   &dwValueSize);
251*1cddb830SAndroid Build Coastguard Worker             // if RegEnumKeyEx fails, we are done with the enumeration
252*1cddb830SAndroid Build Coastguard Worker             if (ERROR_SUCCESS != result)
253*1cddb830SAndroid Build Coastguard Worker             {
254*1cddb830SAndroid Build Coastguard Worker                 KHR_ICD_TRACE("Failed to read value %"PRIuDW", done reading key.\n", dwIndex);
255*1cddb830SAndroid Build Coastguard Worker                 break;
256*1cddb830SAndroid Build Coastguard Worker             }
257*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("Value %s found...\n", cszLibraryName);
258*1cddb830SAndroid Build Coastguard Worker 
259*1cddb830SAndroid Build Coastguard Worker             // Require that the value be a DWORD and equal zero
260*1cddb830SAndroid Build Coastguard Worker             if (REG_DWORD != dwLibraryNameType)
261*1cddb830SAndroid Build Coastguard Worker             {
262*1cddb830SAndroid Build Coastguard Worker                 KHR_ICD_TRACE("Value not a DWORD, skipping\n");
263*1cddb830SAndroid Build Coastguard Worker                 continue;
264*1cddb830SAndroid Build Coastguard Worker             }
265*1cddb830SAndroid Build Coastguard Worker             if (dwValue)
266*1cddb830SAndroid Build Coastguard Worker             {
267*1cddb830SAndroid Build Coastguard Worker                 KHR_ICD_TRACE("Value not zero, skipping\n");
268*1cddb830SAndroid Build Coastguard Worker                 continue;
269*1cddb830SAndroid Build Coastguard Worker             }
270*1cddb830SAndroid Build Coastguard Worker             // add the library
271*1cddb830SAndroid Build Coastguard Worker             status |= adapterAdd(cszLibraryName, ZeroLuid);
272*1cddb830SAndroid Build Coastguard Worker         }
273*1cddb830SAndroid Build Coastguard Worker     }
274*1cddb830SAndroid Build Coastguard Worker 
275*1cddb830SAndroid Build Coastguard Worker     // Add adapters according to DXGI's preference order
276*1cddb830SAndroid Build Coastguard Worker     HMODULE hDXGI = LoadLibraryA("dxgi.dll");
277*1cddb830SAndroid Build Coastguard Worker     if (hDXGI)
278*1cddb830SAndroid Build Coastguard Worker     {
279*1cddb830SAndroid Build Coastguard Worker         IDXGIFactory* pFactory = NULL;
280*1cddb830SAndroid Build Coastguard Worker         PFN_CREATE_DXGI_FACTORY pCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY)GetProcAddress(hDXGI, "CreateDXGIFactory");
281*1cddb830SAndroid Build Coastguard Worker         if (pCreateDXGIFactory)
282*1cddb830SAndroid Build Coastguard Worker         {
283*1cddb830SAndroid Build Coastguard Worker             HRESULT hr = pCreateDXGIFactory(&IID_IDXGIFactory, (void **)&pFactory);
284*1cddb830SAndroid Build Coastguard Worker             if (SUCCEEDED(hr))
285*1cddb830SAndroid Build Coastguard Worker             {
286*1cddb830SAndroid Build Coastguard Worker                 UINT i = 0;
287*1cddb830SAndroid Build Coastguard Worker                 IDXGIAdapter* pAdapter = NULL;
288*1cddb830SAndroid Build Coastguard Worker                 while (SUCCEEDED(pFactory->lpVtbl->EnumAdapters(pFactory, i++, &pAdapter)))
289*1cddb830SAndroid Build Coastguard Worker                 {
290*1cddb830SAndroid Build Coastguard Worker                     DXGI_ADAPTER_DESC AdapterDesc;
291*1cddb830SAndroid Build Coastguard Worker                     if (SUCCEEDED(pAdapter->lpVtbl->GetDesc(pAdapter, &AdapterDesc)))
292*1cddb830SAndroid Build Coastguard Worker                     {
293*1cddb830SAndroid Build Coastguard Worker                         for (WinAdapter* iterAdapter = pWinAdapterBegin; iterAdapter != pWinAdapterEnd; ++iterAdapter)
294*1cddb830SAndroid Build Coastguard Worker                         {
295*1cddb830SAndroid Build Coastguard Worker                             if (iterAdapter->luid.LowPart == AdapterDesc.AdapterLuid.LowPart
296*1cddb830SAndroid Build Coastguard Worker                                 && iterAdapter->luid.HighPart == AdapterDesc.AdapterLuid.HighPart)
297*1cddb830SAndroid Build Coastguard Worker                             {
298*1cddb830SAndroid Build Coastguard Worker                                 khrIcdVendorAdd(iterAdapter->szName);
299*1cddb830SAndroid Build Coastguard Worker                                 break;
300*1cddb830SAndroid Build Coastguard Worker                             }
301*1cddb830SAndroid Build Coastguard Worker                         }
302*1cddb830SAndroid Build Coastguard Worker                     }
303*1cddb830SAndroid Build Coastguard Worker 
304*1cddb830SAndroid Build Coastguard Worker                     pAdapter->lpVtbl->Release(pAdapter);
305*1cddb830SAndroid Build Coastguard Worker                 }
306*1cddb830SAndroid Build Coastguard Worker                 pFactory->lpVtbl->Release(pFactory);
307*1cddb830SAndroid Build Coastguard Worker             }
308*1cddb830SAndroid Build Coastguard Worker         }
309*1cddb830SAndroid Build Coastguard Worker         FreeLibrary(hDXGI);
310*1cddb830SAndroid Build Coastguard Worker     }
311*1cddb830SAndroid Build Coastguard Worker 
312*1cddb830SAndroid Build Coastguard Worker     // Go through the list again, putting any remaining adapters at the end of the list in an undefined order
313*1cddb830SAndroid Build Coastguard Worker     for (WinAdapter* iterAdapter = pWinAdapterBegin; iterAdapter != pWinAdapterEnd; ++iterAdapter)
314*1cddb830SAndroid Build Coastguard Worker     {
315*1cddb830SAndroid Build Coastguard Worker         khrIcdVendorAdd(iterAdapter->szName);
316*1cddb830SAndroid Build Coastguard Worker         adapterFree(iterAdapter);
317*1cddb830SAndroid Build Coastguard Worker     }
318*1cddb830SAndroid Build Coastguard Worker 
319*1cddb830SAndroid Build Coastguard Worker     free(pWinAdapterBegin);
320*1cddb830SAndroid Build Coastguard Worker     pWinAdapterBegin = NULL;
321*1cddb830SAndroid Build Coastguard Worker     pWinAdapterEnd = NULL;
322*1cddb830SAndroid Build Coastguard Worker     pWinAdapterCapacity = NULL;
323*1cddb830SAndroid Build Coastguard Worker 
324*1cddb830SAndroid Build Coastguard Worker     result = RegCloseKey(platformsKey);
325*1cddb830SAndroid Build Coastguard Worker     if (ERROR_SUCCESS != result)
326*1cddb830SAndroid Build Coastguard Worker     {
327*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("Failed to close platforms key %s, ignoring\n", platformsName);
328*1cddb830SAndroid Build Coastguard Worker     }
329*1cddb830SAndroid Build Coastguard Worker 
330*1cddb830SAndroid Build Coastguard Worker #if defined(CL_ENABLE_LAYERS)
331*1cddb830SAndroid Build Coastguard Worker     const char* layersName = "SOFTWARE\\Khronos\\OpenCL\\Layers";
332*1cddb830SAndroid Build Coastguard Worker     HKEY layersKey = NULL;
333*1cddb830SAndroid Build Coastguard Worker 
334*1cddb830SAndroid Build Coastguard Worker     KHR_ICD_TRACE("Opening key HKLM\\%s...\n", layersName);
335*1cddb830SAndroid Build Coastguard Worker     result = RegOpenKeyExA(
336*1cddb830SAndroid Build Coastguard Worker         HKEY_LOCAL_MACHINE,
337*1cddb830SAndroid Build Coastguard Worker         layersName,
338*1cddb830SAndroid Build Coastguard Worker         0,
339*1cddb830SAndroid Build Coastguard Worker         KEY_READ,
340*1cddb830SAndroid Build Coastguard Worker         &layersKey);
341*1cddb830SAndroid Build Coastguard Worker     if (ERROR_SUCCESS != result)
342*1cddb830SAndroid Build Coastguard Worker     {
343*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("Failed to open layers key %s, continuing\n", layersName);
344*1cddb830SAndroid Build Coastguard Worker     }
345*1cddb830SAndroid Build Coastguard Worker     else
346*1cddb830SAndroid Build Coastguard Worker     {
347*1cddb830SAndroid Build Coastguard Worker         // for each value
348*1cddb830SAndroid Build Coastguard Worker         for (dwIndex = 0;; ++dwIndex)
349*1cddb830SAndroid Build Coastguard Worker         {
350*1cddb830SAndroid Build Coastguard Worker             char cszLibraryName[1024] = {0};
351*1cddb830SAndroid Build Coastguard Worker             DWORD dwLibraryNameSize = sizeof(cszLibraryName);
352*1cddb830SAndroid Build Coastguard Worker             DWORD dwLibraryNameType = 0;
353*1cddb830SAndroid Build Coastguard Worker             DWORD dwValue = 0;
354*1cddb830SAndroid Build Coastguard Worker             DWORD dwValueSize = sizeof(dwValue);
355*1cddb830SAndroid Build Coastguard Worker 
356*1cddb830SAndroid Build Coastguard Worker             // read the value name
357*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("Reading value %"PRIuDW"...\n", dwIndex);
358*1cddb830SAndroid Build Coastguard Worker             result = RegEnumValueA(
359*1cddb830SAndroid Build Coastguard Worker                   layersKey,
360*1cddb830SAndroid Build Coastguard Worker                   dwIndex,
361*1cddb830SAndroid Build Coastguard Worker                   cszLibraryName,
362*1cddb830SAndroid Build Coastguard Worker                   &dwLibraryNameSize,
363*1cddb830SAndroid Build Coastguard Worker                   NULL,
364*1cddb830SAndroid Build Coastguard Worker                   &dwLibraryNameType,
365*1cddb830SAndroid Build Coastguard Worker                   (LPBYTE)&dwValue,
366*1cddb830SAndroid Build Coastguard Worker                   &dwValueSize);
367*1cddb830SAndroid Build Coastguard Worker             // if RegEnumKeyEx fails, we are done with the enumeration
368*1cddb830SAndroid Build Coastguard Worker             if (ERROR_SUCCESS != result)
369*1cddb830SAndroid Build Coastguard Worker             {
370*1cddb830SAndroid Build Coastguard Worker                 KHR_ICD_TRACE("Failed to read value %"PRIuDW", done reading key.\n", dwIndex);
371*1cddb830SAndroid Build Coastguard Worker                 break;
372*1cddb830SAndroid Build Coastguard Worker             }
373*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("Value %s found...\n", cszLibraryName);
374*1cddb830SAndroid Build Coastguard Worker 
375*1cddb830SAndroid Build Coastguard Worker             // Require that the value be a DWORD
376*1cddb830SAndroid Build Coastguard Worker             if (REG_DWORD != dwLibraryNameType)
377*1cddb830SAndroid Build Coastguard Worker             {
378*1cddb830SAndroid Build Coastguard Worker                 KHR_ICD_TRACE("Value not a DWORD, skipping\n");
379*1cddb830SAndroid Build Coastguard Worker                 continue;
380*1cddb830SAndroid Build Coastguard Worker             }
381*1cddb830SAndroid Build Coastguard Worker             // add the library
382*1cddb830SAndroid Build Coastguard Worker             status |= layerAdd(cszLibraryName, dwValue);
383*1cddb830SAndroid Build Coastguard Worker         }
384*1cddb830SAndroid Build Coastguard Worker         qsort(pWinLayerBegin, pWinLayerEnd - pWinLayerBegin, sizeof(WinLayer), compareLayer);
385*1cddb830SAndroid Build Coastguard Worker         for (WinLayer* iterLayer = pWinLayerBegin; iterLayer != pWinLayerEnd; ++iterLayer)
386*1cddb830SAndroid Build Coastguard Worker         {
387*1cddb830SAndroid Build Coastguard Worker             khrIcdLayerAdd(iterLayer->szName);
388*1cddb830SAndroid Build Coastguard Worker             layerFree(iterLayer);
389*1cddb830SAndroid Build Coastguard Worker         }
390*1cddb830SAndroid Build Coastguard Worker     }
391*1cddb830SAndroid Build Coastguard Worker 
392*1cddb830SAndroid Build Coastguard Worker     free(pWinLayerBegin);
393*1cddb830SAndroid Build Coastguard Worker     pWinLayerBegin = NULL;
394*1cddb830SAndroid Build Coastguard Worker     pWinLayerEnd = NULL;
395*1cddb830SAndroid Build Coastguard Worker     pWinLayerCapacity = NULL;
396*1cddb830SAndroid Build Coastguard Worker 
397*1cddb830SAndroid Build Coastguard Worker     result = RegCloseKey(layersKey);
398*1cddb830SAndroid Build Coastguard Worker 
399*1cddb830SAndroid Build Coastguard Worker     khrIcdLayersEnumerateEnv();
400*1cddb830SAndroid Build Coastguard Worker #endif // defined(CL_ENABLE_LAYERS)
401*1cddb830SAndroid Build Coastguard Worker     return status;
402*1cddb830SAndroid Build Coastguard Worker }
403*1cddb830SAndroid Build Coastguard Worker 
404*1cddb830SAndroid Build Coastguard Worker // go through the list of vendors only once
khrIcdOsVendorsEnumerateOnce()405*1cddb830SAndroid Build Coastguard Worker void khrIcdOsVendorsEnumerateOnce()
406*1cddb830SAndroid Build Coastguard Worker {
407*1cddb830SAndroid Build Coastguard Worker     InitOnceExecuteOnce(&initialized, khrIcdOsVendorsEnumerate, NULL, NULL);
408*1cddb830SAndroid Build Coastguard Worker }
409*1cddb830SAndroid Build Coastguard Worker 
410*1cddb830SAndroid Build Coastguard Worker /*
411*1cddb830SAndroid Build Coastguard Worker  *
412*1cddb830SAndroid Build Coastguard Worker  * Dynamic library loading functions
413*1cddb830SAndroid Build Coastguard Worker  *
414*1cddb830SAndroid Build Coastguard Worker  */
415*1cddb830SAndroid Build Coastguard Worker 
416*1cddb830SAndroid Build Coastguard Worker // dynamically load a library.  returns NULL on failure
khrIcdOsLibraryLoad(const char * libraryName)417*1cddb830SAndroid Build Coastguard Worker void *khrIcdOsLibraryLoad(const char *libraryName)
418*1cddb830SAndroid Build Coastguard Worker {
419*1cddb830SAndroid Build Coastguard Worker     HMODULE hTemp = LoadLibraryExA(libraryName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
420*1cddb830SAndroid Build Coastguard Worker     if (!hTemp && GetLastError() == ERROR_INVALID_PARAMETER)
421*1cddb830SAndroid Build Coastguard Worker     {
422*1cddb830SAndroid Build Coastguard Worker         hTemp = LoadLibraryExA(libraryName, NULL, 0);
423*1cddb830SAndroid Build Coastguard Worker     }
424*1cddb830SAndroid Build Coastguard Worker     if (!hTemp)
425*1cddb830SAndroid Build Coastguard Worker     {
426*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("Failed to load driver. Windows error code is %"PRIuDW".\n", GetLastError());
427*1cddb830SAndroid Build Coastguard Worker     }
428*1cddb830SAndroid Build Coastguard Worker     return (void*)hTemp;
429*1cddb830SAndroid Build Coastguard Worker }
430*1cddb830SAndroid Build Coastguard Worker 
431*1cddb830SAndroid Build Coastguard Worker // get a function pointer from a loaded library.  returns NULL on failure.
khrIcdOsLibraryGetFunctionAddress(void * library,const char * functionName)432*1cddb830SAndroid Build Coastguard Worker void *khrIcdOsLibraryGetFunctionAddress(void *library, const char *functionName)
433*1cddb830SAndroid Build Coastguard Worker {
434*1cddb830SAndroid Build Coastguard Worker     if (!library || !functionName)
435*1cddb830SAndroid Build Coastguard Worker     {
436*1cddb830SAndroid Build Coastguard Worker         return NULL;
437*1cddb830SAndroid Build Coastguard Worker     }
438*1cddb830SAndroid Build Coastguard Worker     return GetProcAddress( (HMODULE)library, functionName);
439*1cddb830SAndroid Build Coastguard Worker }
440*1cddb830SAndroid Build Coastguard Worker 
441*1cddb830SAndroid Build Coastguard Worker // unload a library.
khrIcdOsLibraryUnload(void * library)442*1cddb830SAndroid Build Coastguard Worker void khrIcdOsLibraryUnload(void *library)
443*1cddb830SAndroid Build Coastguard Worker {
444*1cddb830SAndroid Build Coastguard Worker     FreeLibrary( (HMODULE)library);
445*1cddb830SAndroid Build Coastguard Worker }
446