xref: /aosp_15_r20/external/OpenCL-ICD-Loader/loader/icd.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 "icd.h"
20*1cddb830SAndroid Build Coastguard Worker #include "icd_dispatch.h"
21*1cddb830SAndroid Build Coastguard Worker #include "icd_envvars.h"
22*1cddb830SAndroid Build Coastguard Worker #if defined(CL_ENABLE_LAYERS)
23*1cddb830SAndroid Build Coastguard Worker #include <CL/cl_layer.h>
24*1cddb830SAndroid Build Coastguard Worker #endif // defined(CL_ENABLE_LAYERS)
25*1cddb830SAndroid Build Coastguard Worker #include <stdlib.h>
26*1cddb830SAndroid Build Coastguard Worker #include <string.h>
27*1cddb830SAndroid Build Coastguard Worker 
28*1cddb830SAndroid Build Coastguard Worker KHRicdVendor *khrIcdVendors = NULL;
29*1cddb830SAndroid Build Coastguard Worker int khrEnableTrace = 0;
30*1cddb830SAndroid Build Coastguard Worker 
31*1cddb830SAndroid Build Coastguard Worker #if defined(CL_ENABLE_LAYERS)
32*1cddb830SAndroid Build Coastguard Worker struct KHRLayer *khrFirstLayer = NULL;
33*1cddb830SAndroid Build Coastguard Worker #endif // defined(CL_ENABLE_LAYERS)
34*1cddb830SAndroid Build Coastguard Worker 
35*1cddb830SAndroid Build Coastguard Worker // entrypoint to check and initialize trace.
khrIcdInitializeTrace(void)36*1cddb830SAndroid Build Coastguard Worker void khrIcdInitializeTrace(void)
37*1cddb830SAndroid Build Coastguard Worker {
38*1cddb830SAndroid Build Coastguard Worker     char *enableTrace = khrIcd_getenv("OCL_ICD_ENABLE_TRACE");
39*1cddb830SAndroid Build Coastguard Worker     if (enableTrace && (strcmp(enableTrace, "True") == 0 ||
40*1cddb830SAndroid Build Coastguard Worker             strcmp(enableTrace, "true") == 0 ||
41*1cddb830SAndroid Build Coastguard Worker             strcmp(enableTrace, "T") == 0 ||
42*1cddb830SAndroid Build Coastguard Worker             strcmp(enableTrace, "1") == 0))
43*1cddb830SAndroid Build Coastguard Worker     {
44*1cddb830SAndroid Build Coastguard Worker         khrEnableTrace = 1;
45*1cddb830SAndroid Build Coastguard Worker     }
46*1cddb830SAndroid Build Coastguard Worker }
47*1cddb830SAndroid Build Coastguard Worker 
48*1cddb830SAndroid Build Coastguard Worker // entrypoint to initialize the ICD and add all vendors
khrIcdInitialize(void)49*1cddb830SAndroid Build Coastguard Worker void khrIcdInitialize(void)
50*1cddb830SAndroid Build Coastguard Worker {
51*1cddb830SAndroid Build Coastguard Worker     // enumerate vendors present on the system
52*1cddb830SAndroid Build Coastguard Worker     khrIcdOsVendorsEnumerateOnce();
53*1cddb830SAndroid Build Coastguard Worker }
54*1cddb830SAndroid Build Coastguard Worker 
khrIcdVendorAdd(const char * libraryName)55*1cddb830SAndroid Build Coastguard Worker void khrIcdVendorAdd(const char *libraryName)
56*1cddb830SAndroid Build Coastguard Worker {
57*1cddb830SAndroid Build Coastguard Worker     void *library = NULL;
58*1cddb830SAndroid Build Coastguard Worker     cl_int result = CL_SUCCESS;
59*1cddb830SAndroid Build Coastguard Worker     pfn_clGetExtensionFunctionAddress p_clGetExtensionFunctionAddress = NULL;
60*1cddb830SAndroid Build Coastguard Worker     pfn_clIcdGetPlatformIDs p_clIcdGetPlatformIDs = NULL;
61*1cddb830SAndroid Build Coastguard Worker     cl_uint i = 0;
62*1cddb830SAndroid Build Coastguard Worker     cl_uint platformCount = 0;
63*1cddb830SAndroid Build Coastguard Worker     cl_platform_id *platforms = NULL;
64*1cddb830SAndroid Build Coastguard Worker     KHRicdVendor *vendorIterator = NULL;
65*1cddb830SAndroid Build Coastguard Worker 
66*1cddb830SAndroid Build Coastguard Worker     // require that the library name be valid
67*1cddb830SAndroid Build Coastguard Worker     if (!libraryName)
68*1cddb830SAndroid Build Coastguard Worker     {
69*1cddb830SAndroid Build Coastguard Worker         goto Done;
70*1cddb830SAndroid Build Coastguard Worker     }
71*1cddb830SAndroid Build Coastguard Worker     KHR_ICD_TRACE("attempting to add vendor %s...\n", libraryName);
72*1cddb830SAndroid Build Coastguard Worker 
73*1cddb830SAndroid Build Coastguard Worker     // load its library and query its function pointers
74*1cddb830SAndroid Build Coastguard Worker     library = khrIcdOsLibraryLoad(libraryName);
75*1cddb830SAndroid Build Coastguard Worker     if (!library)
76*1cddb830SAndroid Build Coastguard Worker     {
77*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("failed to load library %s\n", libraryName);
78*1cddb830SAndroid Build Coastguard Worker         goto Done;
79*1cddb830SAndroid Build Coastguard Worker     }
80*1cddb830SAndroid Build Coastguard Worker 
81*1cddb830SAndroid Build Coastguard Worker     // ensure that we haven't already loaded this vendor
82*1cddb830SAndroid Build Coastguard Worker     for (vendorIterator = khrIcdVendors; vendorIterator; vendorIterator = vendorIterator->next)
83*1cddb830SAndroid Build Coastguard Worker     {
84*1cddb830SAndroid Build Coastguard Worker         if (vendorIterator->library == library)
85*1cddb830SAndroid Build Coastguard Worker         {
86*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("already loaded vendor %s, nothing to do here\n", libraryName);
87*1cddb830SAndroid Build Coastguard Worker             goto Done;
88*1cddb830SAndroid Build Coastguard Worker         }
89*1cddb830SAndroid Build Coastguard Worker     }
90*1cddb830SAndroid Build Coastguard Worker 
91*1cddb830SAndroid Build Coastguard Worker     // get the library's clGetExtensionFunctionAddress pointer
92*1cddb830SAndroid Build Coastguard Worker     p_clGetExtensionFunctionAddress = (pfn_clGetExtensionFunctionAddress)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "clGetExtensionFunctionAddress");
93*1cddb830SAndroid Build Coastguard Worker     if (!p_clGetExtensionFunctionAddress)
94*1cddb830SAndroid Build Coastguard Worker     {
95*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("failed to get function address clGetExtensionFunctionAddress\n");
96*1cddb830SAndroid Build Coastguard Worker         goto Done;
97*1cddb830SAndroid Build Coastguard Worker     }
98*1cddb830SAndroid Build Coastguard Worker 
99*1cddb830SAndroid Build Coastguard Worker     // use that function to get the clIcdGetPlatformIDsKHR function pointer
100*1cddb830SAndroid Build Coastguard Worker     p_clIcdGetPlatformIDs = (pfn_clIcdGetPlatformIDs)(size_t)p_clGetExtensionFunctionAddress("clIcdGetPlatformIDsKHR");
101*1cddb830SAndroid Build Coastguard Worker     if (!p_clIcdGetPlatformIDs)
102*1cddb830SAndroid Build Coastguard Worker     {
103*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("failed to get extension function address clIcdGetPlatformIDsKHR\n");
104*1cddb830SAndroid Build Coastguard Worker         goto Done;
105*1cddb830SAndroid Build Coastguard Worker     }
106*1cddb830SAndroid Build Coastguard Worker 
107*1cddb830SAndroid Build Coastguard Worker     // query the number of platforms available and allocate space to store them
108*1cddb830SAndroid Build Coastguard Worker     result = p_clIcdGetPlatformIDs(0, NULL, &platformCount);
109*1cddb830SAndroid Build Coastguard Worker     if (CL_SUCCESS != result)
110*1cddb830SAndroid Build Coastguard Worker     {
111*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("failed clIcdGetPlatformIDs\n");
112*1cddb830SAndroid Build Coastguard Worker         goto Done;
113*1cddb830SAndroid Build Coastguard Worker     }
114*1cddb830SAndroid Build Coastguard Worker     platforms = (cl_platform_id *)malloc(platformCount * sizeof(cl_platform_id) );
115*1cddb830SAndroid Build Coastguard Worker     if (!platforms)
116*1cddb830SAndroid Build Coastguard Worker     {
117*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("failed to allocate memory\n");
118*1cddb830SAndroid Build Coastguard Worker         goto Done;
119*1cddb830SAndroid Build Coastguard Worker     }
120*1cddb830SAndroid Build Coastguard Worker     memset(platforms, 0, platformCount * sizeof(cl_platform_id) );
121*1cddb830SAndroid Build Coastguard Worker     result = p_clIcdGetPlatformIDs(platformCount, platforms, NULL);
122*1cddb830SAndroid Build Coastguard Worker     if (CL_SUCCESS != result)
123*1cddb830SAndroid Build Coastguard Worker     {
124*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("failed clIcdGetPlatformIDs\n");
125*1cddb830SAndroid Build Coastguard Worker         goto Done;
126*1cddb830SAndroid Build Coastguard Worker     }
127*1cddb830SAndroid Build Coastguard Worker 
128*1cddb830SAndroid Build Coastguard Worker     // for each platform, add it
129*1cddb830SAndroid Build Coastguard Worker     for (i = 0; i < platformCount; ++i)
130*1cddb830SAndroid Build Coastguard Worker     {
131*1cddb830SAndroid Build Coastguard Worker         KHRicdVendor* vendor = NULL;
132*1cddb830SAndroid Build Coastguard Worker         char *suffix;
133*1cddb830SAndroid Build Coastguard Worker         size_t suffixSize;
134*1cddb830SAndroid Build Coastguard Worker 
135*1cddb830SAndroid Build Coastguard Worker         // call clGetPlatformInfo on the returned platform to get the suffix
136*1cddb830SAndroid Build Coastguard Worker         if (!platforms[i])
137*1cddb830SAndroid Build Coastguard Worker         {
138*1cddb830SAndroid Build Coastguard Worker             continue;
139*1cddb830SAndroid Build Coastguard Worker         }
140*1cddb830SAndroid Build Coastguard Worker         result = platforms[i]->dispatch->clGetPlatformInfo(
141*1cddb830SAndroid Build Coastguard Worker             platforms[i],
142*1cddb830SAndroid Build Coastguard Worker             CL_PLATFORM_ICD_SUFFIX_KHR,
143*1cddb830SAndroid Build Coastguard Worker             0,
144*1cddb830SAndroid Build Coastguard Worker             NULL,
145*1cddb830SAndroid Build Coastguard Worker             &suffixSize);
146*1cddb830SAndroid Build Coastguard Worker         if (CL_SUCCESS != result)
147*1cddb830SAndroid Build Coastguard Worker         {
148*1cddb830SAndroid Build Coastguard Worker             continue;
149*1cddb830SAndroid Build Coastguard Worker         }
150*1cddb830SAndroid Build Coastguard Worker         suffix = (char *)malloc(suffixSize);
151*1cddb830SAndroid Build Coastguard Worker         if (!suffix)
152*1cddb830SAndroid Build Coastguard Worker         {
153*1cddb830SAndroid Build Coastguard Worker             continue;
154*1cddb830SAndroid Build Coastguard Worker         }
155*1cddb830SAndroid Build Coastguard Worker         result = platforms[i]->dispatch->clGetPlatformInfo(
156*1cddb830SAndroid Build Coastguard Worker             platforms[i],
157*1cddb830SAndroid Build Coastguard Worker             CL_PLATFORM_ICD_SUFFIX_KHR,
158*1cddb830SAndroid Build Coastguard Worker             suffixSize,
159*1cddb830SAndroid Build Coastguard Worker             suffix,
160*1cddb830SAndroid Build Coastguard Worker             NULL);
161*1cddb830SAndroid Build Coastguard Worker         if (CL_SUCCESS != result)
162*1cddb830SAndroid Build Coastguard Worker         {
163*1cddb830SAndroid Build Coastguard Worker             free(suffix);
164*1cddb830SAndroid Build Coastguard Worker             continue;
165*1cddb830SAndroid Build Coastguard Worker         }
166*1cddb830SAndroid Build Coastguard Worker 
167*1cddb830SAndroid Build Coastguard Worker         // allocate a structure for the vendor
168*1cddb830SAndroid Build Coastguard Worker         vendor = (KHRicdVendor*)malloc(sizeof(*vendor) );
169*1cddb830SAndroid Build Coastguard Worker         if (!vendor)
170*1cddb830SAndroid Build Coastguard Worker         {
171*1cddb830SAndroid Build Coastguard Worker             free(suffix);
172*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("failed to allocate memory\n");
173*1cddb830SAndroid Build Coastguard Worker             continue;
174*1cddb830SAndroid Build Coastguard Worker         }
175*1cddb830SAndroid Build Coastguard Worker         memset(vendor, 0, sizeof(*vendor) );
176*1cddb830SAndroid Build Coastguard Worker 
177*1cddb830SAndroid Build Coastguard Worker         // populate vendor data
178*1cddb830SAndroid Build Coastguard Worker         vendor->library = khrIcdOsLibraryLoad(libraryName);
179*1cddb830SAndroid Build Coastguard Worker         if (!vendor->library)
180*1cddb830SAndroid Build Coastguard Worker         {
181*1cddb830SAndroid Build Coastguard Worker             free(suffix);
182*1cddb830SAndroid Build Coastguard Worker             free(vendor);
183*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("failed get platform handle to library\n");
184*1cddb830SAndroid Build Coastguard Worker             continue;
185*1cddb830SAndroid Build Coastguard Worker         }
186*1cddb830SAndroid Build Coastguard Worker         vendor->clGetExtensionFunctionAddress = p_clGetExtensionFunctionAddress;
187*1cddb830SAndroid Build Coastguard Worker         vendor->platform = platforms[i];
188*1cddb830SAndroid Build Coastguard Worker         vendor->suffix = suffix;
189*1cddb830SAndroid Build Coastguard Worker 
190*1cddb830SAndroid Build Coastguard Worker         // add this vendor to the list of vendors at the tail
191*1cddb830SAndroid Build Coastguard Worker         {
192*1cddb830SAndroid Build Coastguard Worker             KHRicdVendor **prevNextPointer = NULL;
193*1cddb830SAndroid Build Coastguard Worker             for (prevNextPointer = &khrIcdVendors; *prevNextPointer; prevNextPointer = &( (*prevNextPointer)->next) );
194*1cddb830SAndroid Build Coastguard Worker             *prevNextPointer = vendor;
195*1cddb830SAndroid Build Coastguard Worker         }
196*1cddb830SAndroid Build Coastguard Worker 
197*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("successfully added vendor %s with suffix %s\n", libraryName, suffix);
198*1cddb830SAndroid Build Coastguard Worker 
199*1cddb830SAndroid Build Coastguard Worker     }
200*1cddb830SAndroid Build Coastguard Worker 
201*1cddb830SAndroid Build Coastguard Worker Done:
202*1cddb830SAndroid Build Coastguard Worker 
203*1cddb830SAndroid Build Coastguard Worker     if (library)
204*1cddb830SAndroid Build Coastguard Worker     {
205*1cddb830SAndroid Build Coastguard Worker         khrIcdOsLibraryUnload(library);
206*1cddb830SAndroid Build Coastguard Worker     }
207*1cddb830SAndroid Build Coastguard Worker     if (platforms)
208*1cddb830SAndroid Build Coastguard Worker     {
209*1cddb830SAndroid Build Coastguard Worker         free(platforms);
210*1cddb830SAndroid Build Coastguard Worker     }
211*1cddb830SAndroid Build Coastguard Worker }
212*1cddb830SAndroid Build Coastguard Worker 
213*1cddb830SAndroid Build Coastguard Worker #if defined(CL_ENABLE_LAYERS)
khrIcdLayerAdd(const char * libraryName)214*1cddb830SAndroid Build Coastguard Worker void khrIcdLayerAdd(const char *libraryName)
215*1cddb830SAndroid Build Coastguard Worker {
216*1cddb830SAndroid Build Coastguard Worker     void *library = NULL;
217*1cddb830SAndroid Build Coastguard Worker     cl_int result = CL_SUCCESS;
218*1cddb830SAndroid Build Coastguard Worker     pfn_clGetLayerInfo p_clGetLayerInfo = NULL;
219*1cddb830SAndroid Build Coastguard Worker     pfn_clInitLayer p_clInitLayer = NULL;
220*1cddb830SAndroid Build Coastguard Worker     struct KHRLayer *layerIterator = NULL;
221*1cddb830SAndroid Build Coastguard Worker     struct KHRLayer *layer = NULL;
222*1cddb830SAndroid Build Coastguard Worker     cl_layer_api_version api_version = 0;
223*1cddb830SAndroid Build Coastguard Worker     const struct _cl_icd_dispatch *targetDispatch = NULL;
224*1cddb830SAndroid Build Coastguard Worker     const struct _cl_icd_dispatch *layerDispatch = NULL;
225*1cddb830SAndroid Build Coastguard Worker     cl_uint layerDispatchNumEntries = 0;
226*1cddb830SAndroid Build Coastguard Worker     cl_uint loaderDispatchNumEntries = 0;
227*1cddb830SAndroid Build Coastguard Worker 
228*1cddb830SAndroid Build Coastguard Worker     // require that the library name be valid
229*1cddb830SAndroid Build Coastguard Worker     if (!libraryName)
230*1cddb830SAndroid Build Coastguard Worker     {
231*1cddb830SAndroid Build Coastguard Worker         goto Done;
232*1cddb830SAndroid Build Coastguard Worker     }
233*1cddb830SAndroid Build Coastguard Worker     KHR_ICD_TRACE("attempting to add layer %s...\n", libraryName);
234*1cddb830SAndroid Build Coastguard Worker 
235*1cddb830SAndroid Build Coastguard Worker     // load its library and query its function pointers
236*1cddb830SAndroid Build Coastguard Worker     library = khrIcdOsLibraryLoad(libraryName);
237*1cddb830SAndroid Build Coastguard Worker     if (!library)
238*1cddb830SAndroid Build Coastguard Worker     {
239*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("failed to load library %s\n", libraryName);
240*1cddb830SAndroid Build Coastguard Worker         goto Done;
241*1cddb830SAndroid Build Coastguard Worker     }
242*1cddb830SAndroid Build Coastguard Worker 
243*1cddb830SAndroid Build Coastguard Worker     // ensure that we haven't already loaded this layer
244*1cddb830SAndroid Build Coastguard Worker     for (layerIterator = khrFirstLayer; layerIterator; layerIterator = layerIterator->next)
245*1cddb830SAndroid Build Coastguard Worker     {
246*1cddb830SAndroid Build Coastguard Worker         if (layerIterator->library == library)
247*1cddb830SAndroid Build Coastguard Worker         {
248*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("already loaded layer %s, nothing to do here\n", libraryName);
249*1cddb830SAndroid Build Coastguard Worker             goto Done;
250*1cddb830SAndroid Build Coastguard Worker         }
251*1cddb830SAndroid Build Coastguard Worker     }
252*1cddb830SAndroid Build Coastguard Worker 
253*1cddb830SAndroid Build Coastguard Worker     // get the library's clGetLayerInfo pointer
254*1cddb830SAndroid Build Coastguard Worker     p_clGetLayerInfo = (pfn_clGetLayerInfo)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "clGetLayerInfo");
255*1cddb830SAndroid Build Coastguard Worker     if (!p_clGetLayerInfo)
256*1cddb830SAndroid Build Coastguard Worker     {
257*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("failed to get function address clGetLayerInfo\n");
258*1cddb830SAndroid Build Coastguard Worker         goto Done;
259*1cddb830SAndroid Build Coastguard Worker     }
260*1cddb830SAndroid Build Coastguard Worker 
261*1cddb830SAndroid Build Coastguard Worker     // use that function to get the clInitLayer function pointer
262*1cddb830SAndroid Build Coastguard Worker     p_clInitLayer = (pfn_clInitLayer)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "clInitLayer");
263*1cddb830SAndroid Build Coastguard Worker     if (!p_clInitLayer)
264*1cddb830SAndroid Build Coastguard Worker     {
265*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("failed to get function address clInitLayer\n");
266*1cddb830SAndroid Build Coastguard Worker         goto Done;
267*1cddb830SAndroid Build Coastguard Worker     }
268*1cddb830SAndroid Build Coastguard Worker 
269*1cddb830SAndroid Build Coastguard Worker     result = p_clGetLayerInfo(CL_LAYER_API_VERSION, sizeof(api_version), &api_version, NULL);
270*1cddb830SAndroid Build Coastguard Worker     if (CL_SUCCESS != result)
271*1cddb830SAndroid Build Coastguard Worker     {
272*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("failed to query layer version\n");
273*1cddb830SAndroid Build Coastguard Worker         goto Done;
274*1cddb830SAndroid Build Coastguard Worker     }
275*1cddb830SAndroid Build Coastguard Worker 
276*1cddb830SAndroid Build Coastguard Worker     if (CL_LAYER_API_VERSION_100 != api_version)
277*1cddb830SAndroid Build Coastguard Worker     {
278*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("unsupported api version\n");
279*1cddb830SAndroid Build Coastguard Worker         goto Done;
280*1cddb830SAndroid Build Coastguard Worker     }
281*1cddb830SAndroid Build Coastguard Worker 
282*1cddb830SAndroid Build Coastguard Worker     layer = (struct KHRLayer*)calloc(sizeof(struct KHRLayer), 1);
283*1cddb830SAndroid Build Coastguard Worker     if (!layer)
284*1cddb830SAndroid Build Coastguard Worker     {
285*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("failed to allocate memory\n");
286*1cddb830SAndroid Build Coastguard Worker         goto Done;
287*1cddb830SAndroid Build Coastguard Worker     }
288*1cddb830SAndroid Build Coastguard Worker #ifdef CL_LAYER_INFO
289*1cddb830SAndroid Build Coastguard Worker     {
290*1cddb830SAndroid Build Coastguard Worker         // Not using strdup as it is not standard c
291*1cddb830SAndroid Build Coastguard Worker         size_t sz_name = strlen(libraryName) + 1;
292*1cddb830SAndroid Build Coastguard Worker         layer->libraryName = malloc(sz_name);
293*1cddb830SAndroid Build Coastguard Worker         if (!layer->libraryName)
294*1cddb830SAndroid Build Coastguard Worker         {
295*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("failed to allocate memory\n");
296*1cddb830SAndroid Build Coastguard Worker             goto Done;
297*1cddb830SAndroid Build Coastguard Worker         }
298*1cddb830SAndroid Build Coastguard Worker         memcpy(layer->libraryName, libraryName, sz_name);
299*1cddb830SAndroid Build Coastguard Worker         layer->p_clGetLayerInfo = (void *)(size_t)p_clGetLayerInfo;
300*1cddb830SAndroid Build Coastguard Worker     }
301*1cddb830SAndroid Build Coastguard Worker #endif
302*1cddb830SAndroid Build Coastguard Worker 
303*1cddb830SAndroid Build Coastguard Worker     if (khrFirstLayer) {
304*1cddb830SAndroid Build Coastguard Worker         targetDispatch = &(khrFirstLayer->dispatch);
305*1cddb830SAndroid Build Coastguard Worker     } else {
306*1cddb830SAndroid Build Coastguard Worker         targetDispatch = &khrMasterDispatch;
307*1cddb830SAndroid Build Coastguard Worker     }
308*1cddb830SAndroid Build Coastguard Worker 
309*1cddb830SAndroid Build Coastguard Worker     loaderDispatchNumEntries = sizeof(khrMasterDispatch)/sizeof(void*);
310*1cddb830SAndroid Build Coastguard Worker     result = p_clInitLayer(
311*1cddb830SAndroid Build Coastguard Worker         loaderDispatchNumEntries,
312*1cddb830SAndroid Build Coastguard Worker         targetDispatch,
313*1cddb830SAndroid Build Coastguard Worker         &layerDispatchNumEntries,
314*1cddb830SAndroid Build Coastguard Worker         &layerDispatch);
315*1cddb830SAndroid Build Coastguard Worker     if (CL_SUCCESS != result)
316*1cddb830SAndroid Build Coastguard Worker     {
317*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("failed to initialize layer\n");
318*1cddb830SAndroid Build Coastguard Worker         goto Done;
319*1cddb830SAndroid Build Coastguard Worker     }
320*1cddb830SAndroid Build Coastguard Worker 
321*1cddb830SAndroid Build Coastguard Worker     layer->next = khrFirstLayer;
322*1cddb830SAndroid Build Coastguard Worker     khrFirstLayer = layer;
323*1cddb830SAndroid Build Coastguard Worker     layer->library = library;
324*1cddb830SAndroid Build Coastguard Worker 
325*1cddb830SAndroid Build Coastguard Worker     cl_uint limit = layerDispatchNumEntries < loaderDispatchNumEntries ? layerDispatchNumEntries : loaderDispatchNumEntries;
326*1cddb830SAndroid Build Coastguard Worker 
327*1cddb830SAndroid Build Coastguard Worker     for (cl_uint i = 0; i < limit; i++) {
328*1cddb830SAndroid Build Coastguard Worker         ((void **)&(layer->dispatch))[i] =
329*1cddb830SAndroid Build Coastguard Worker             ((void **)layerDispatch)[i] ?
330*1cddb830SAndroid Build Coastguard Worker                 ((void **)layerDispatch)[i] : ((void **)targetDispatch)[i];
331*1cddb830SAndroid Build Coastguard Worker     }
332*1cddb830SAndroid Build Coastguard Worker     for (cl_uint i = limit; i < loaderDispatchNumEntries; i++) {
333*1cddb830SAndroid Build Coastguard Worker         ((void **)&(layer->dispatch))[i] = ((void **)targetDispatch)[i];
334*1cddb830SAndroid Build Coastguard Worker     }
335*1cddb830SAndroid Build Coastguard Worker 
336*1cddb830SAndroid Build Coastguard Worker     KHR_ICD_TRACE("successfully added layer %s\n", libraryName);
337*1cddb830SAndroid Build Coastguard Worker     return;
338*1cddb830SAndroid Build Coastguard Worker Done:
339*1cddb830SAndroid Build Coastguard Worker     if (library)
340*1cddb830SAndroid Build Coastguard Worker     {
341*1cddb830SAndroid Build Coastguard Worker         khrIcdOsLibraryUnload(library);
342*1cddb830SAndroid Build Coastguard Worker     }
343*1cddb830SAndroid Build Coastguard Worker     if (layer)
344*1cddb830SAndroid Build Coastguard Worker     {
345*1cddb830SAndroid Build Coastguard Worker         free(layer);
346*1cddb830SAndroid Build Coastguard Worker     }
347*1cddb830SAndroid Build Coastguard Worker }
348*1cddb830SAndroid Build Coastguard Worker #endif // defined(CL_ENABLE_LAYERS)
349*1cddb830SAndroid Build Coastguard Worker 
350*1cddb830SAndroid Build Coastguard Worker // Get next file or dirname given a string list or registry key path.
351*1cddb830SAndroid Build Coastguard Worker // Note: the input string may be modified!
loader_get_next_path(char * path)352*1cddb830SAndroid Build Coastguard Worker static char *loader_get_next_path(char *path) {
353*1cddb830SAndroid Build Coastguard Worker     size_t len;
354*1cddb830SAndroid Build Coastguard Worker     char *next;
355*1cddb830SAndroid Build Coastguard Worker 
356*1cddb830SAndroid Build Coastguard Worker     if (path == NULL) return NULL;
357*1cddb830SAndroid Build Coastguard Worker     next = strchr(path, PATH_SEPARATOR);
358*1cddb830SAndroid Build Coastguard Worker     if (next == NULL) {
359*1cddb830SAndroid Build Coastguard Worker         len = strlen(path);
360*1cddb830SAndroid Build Coastguard Worker         next = path + len;
361*1cddb830SAndroid Build Coastguard Worker     } else {
362*1cddb830SAndroid Build Coastguard Worker         *next = '\0';
363*1cddb830SAndroid Build Coastguard Worker         next++;
364*1cddb830SAndroid Build Coastguard Worker     }
365*1cddb830SAndroid Build Coastguard Worker 
366*1cddb830SAndroid Build Coastguard Worker     return next;
367*1cddb830SAndroid Build Coastguard Worker }
368*1cddb830SAndroid Build Coastguard Worker 
khrIcdVendorsEnumerateEnv(void)369*1cddb830SAndroid Build Coastguard Worker void khrIcdVendorsEnumerateEnv(void)
370*1cddb830SAndroid Build Coastguard Worker {
371*1cddb830SAndroid Build Coastguard Worker     char* icdFilenames = khrIcd_secure_getenv("OCL_ICD_FILENAMES");
372*1cddb830SAndroid Build Coastguard Worker     char* cur_file = NULL;
373*1cddb830SAndroid Build Coastguard Worker     char* next_file = NULL;
374*1cddb830SAndroid Build Coastguard Worker     if (icdFilenames)
375*1cddb830SAndroid Build Coastguard Worker     {
376*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("Found OCL_ICD_FILENAMES environment variable.\n");
377*1cddb830SAndroid Build Coastguard Worker 
378*1cddb830SAndroid Build Coastguard Worker         next_file = icdFilenames;
379*1cddb830SAndroid Build Coastguard Worker         while (NULL != next_file && *next_file != '\0') {
380*1cddb830SAndroid Build Coastguard Worker             cur_file = next_file;
381*1cddb830SAndroid Build Coastguard Worker             next_file = loader_get_next_path(cur_file);
382*1cddb830SAndroid Build Coastguard Worker 
383*1cddb830SAndroid Build Coastguard Worker             khrIcdVendorAdd(cur_file);
384*1cddb830SAndroid Build Coastguard Worker         }
385*1cddb830SAndroid Build Coastguard Worker 
386*1cddb830SAndroid Build Coastguard Worker         khrIcd_free_getenv(icdFilenames);
387*1cddb830SAndroid Build Coastguard Worker     }
388*1cddb830SAndroid Build Coastguard Worker }
389*1cddb830SAndroid Build Coastguard Worker 
390*1cddb830SAndroid Build Coastguard Worker #if defined(CL_ENABLE_LAYERS)
khrIcdLayersEnumerateEnv(void)391*1cddb830SAndroid Build Coastguard Worker void khrIcdLayersEnumerateEnv(void)
392*1cddb830SAndroid Build Coastguard Worker {
393*1cddb830SAndroid Build Coastguard Worker     char* layerFilenames = khrIcd_secure_getenv("OPENCL_LAYERS");
394*1cddb830SAndroid Build Coastguard Worker     char* cur_file = NULL;
395*1cddb830SAndroid Build Coastguard Worker     char* next_file = NULL;
396*1cddb830SAndroid Build Coastguard Worker     if (layerFilenames)
397*1cddb830SAndroid Build Coastguard Worker     {
398*1cddb830SAndroid Build Coastguard Worker         KHR_ICD_TRACE("Found OPENCL_LAYERS environment variable.\n");
399*1cddb830SAndroid Build Coastguard Worker 
400*1cddb830SAndroid Build Coastguard Worker         next_file = layerFilenames;
401*1cddb830SAndroid Build Coastguard Worker         while (NULL != next_file && *next_file != '\0') {
402*1cddb830SAndroid Build Coastguard Worker             cur_file = next_file;
403*1cddb830SAndroid Build Coastguard Worker             next_file = loader_get_next_path(cur_file);
404*1cddb830SAndroid Build Coastguard Worker 
405*1cddb830SAndroid Build Coastguard Worker             khrIcdLayerAdd(cur_file);
406*1cddb830SAndroid Build Coastguard Worker         }
407*1cddb830SAndroid Build Coastguard Worker 
408*1cddb830SAndroid Build Coastguard Worker         khrIcd_free_getenv(layerFilenames);
409*1cddb830SAndroid Build Coastguard Worker     }
410*1cddb830SAndroid Build Coastguard Worker }
411*1cddb830SAndroid Build Coastguard Worker #endif // defined(CL_ENABLE_LAYERS)
412*1cddb830SAndroid Build Coastguard Worker 
khrIcdContextPropertiesGetPlatform(const cl_context_properties * properties,cl_platform_id * outPlatform)413*1cddb830SAndroid Build Coastguard Worker void khrIcdContextPropertiesGetPlatform(const cl_context_properties *properties, cl_platform_id *outPlatform)
414*1cddb830SAndroid Build Coastguard Worker {
415*1cddb830SAndroid Build Coastguard Worker     if (properties == NULL && khrIcdVendors != NULL)
416*1cddb830SAndroid Build Coastguard Worker     {
417*1cddb830SAndroid Build Coastguard Worker         *outPlatform = khrIcdVendors[0].platform;
418*1cddb830SAndroid Build Coastguard Worker     }
419*1cddb830SAndroid Build Coastguard Worker     else
420*1cddb830SAndroid Build Coastguard Worker     {
421*1cddb830SAndroid Build Coastguard Worker         const cl_context_properties *property = (cl_context_properties *)NULL;
422*1cddb830SAndroid Build Coastguard Worker         *outPlatform = NULL;
423*1cddb830SAndroid Build Coastguard Worker         for (property = properties; property && property[0]; property += 2)
424*1cddb830SAndroid Build Coastguard Worker         {
425*1cddb830SAndroid Build Coastguard Worker             if ((cl_context_properties)CL_CONTEXT_PLATFORM == property[0])
426*1cddb830SAndroid Build Coastguard Worker             {
427*1cddb830SAndroid Build Coastguard Worker                 *outPlatform = (cl_platform_id)property[1];
428*1cddb830SAndroid Build Coastguard Worker             }
429*1cddb830SAndroid Build Coastguard Worker         }
430*1cddb830SAndroid Build Coastguard Worker     }
431*1cddb830SAndroid Build Coastguard Worker }
432*1cddb830SAndroid Build Coastguard Worker 
433