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