2 * Copyright (c) 2016 The Khronos Group Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software source and associated documentation files (the "Materials"),
6 * to deal in the Materials without restriction, including without limitation
7 * the rights to use, copy, modify, compile, merge, publish, distribute,
8 * sublicense, and/or sell copies of the Materials, and to permit persons to
9 * whom the Materials are furnished to do so, subject the following terms and
12 * All modifications to the Materials used to create a binary that is
13 * distributed to third parties shall be provided to Khronos with an
14 * unrestricted license to use for the purposes of implementing bug fixes and
15 * enhancements to the Materials;
17 * If the binary is used as part of an OpenCL(TM) implementation, whether binary
18 * is distributed together with or separately to that implementation, then
19 * recipient must become an OpenCL Adopter and follow the published OpenCL
20 * conformance process for that implementation, details at:
21 * http://www.khronos.org/conformance/;
23 * The above copyright notice, the OpenCL trademark license, and this permission
24 * notice shall be included in all copies or substantial portions of the
27 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32 * OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS IN
35 * OpenCL is a trademark of Apple Inc. used under license by Khronos.
39 #include "icd_dispatch.h"
43 KHRicdVendor *khrIcdVendors = NULL;
45 // entrypoint to initialize the ICD and add all vendors
46 void khrIcdInitialize(void)
48 // enumerate vendors present on the system
49 khrIcdOsVendorsEnumerateOnce();
52 void khrIcdVendorAdd(const char *libraryName)
55 cl_int result = CL_SUCCESS;
56 pfn_clGetExtensionFunctionAddress p_clGetExtensionFunctionAddress = NULL;
57 pfn_clIcdGetPlatformIDs p_clIcdGetPlatformIDs = NULL;
59 cl_uint platformCount = 0;
60 cl_platform_id *platforms = NULL;
61 KHRicdVendor *vendorIterator = NULL;
63 // require that the library name be valid
68 KHR_ICD_TRACE("attempting to add vendor %s...\n", libraryName);
70 // load its library and query its function pointers
71 library = khrIcdOsLibraryLoad(libraryName);
74 KHR_ICD_TRACE("failed to load library %s\n", libraryName);
78 // ensure that we haven't already loaded this vendor
79 for (vendorIterator = khrIcdVendors; vendorIterator; vendorIterator = vendorIterator->next)
81 if (vendorIterator->library == library)
83 KHR_ICD_TRACE("already loaded vendor %s, nothing to do here\n", libraryName);
88 // get the library's clGetExtensionFunctionAddress pointer
89 p_clGetExtensionFunctionAddress = (pfn_clGetExtensionFunctionAddress)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "clGetExtensionFunctionAddress");
90 if (!p_clGetExtensionFunctionAddress)
92 KHR_ICD_TRACE("failed to get function address clGetExtensionFunctionAddress\n");
96 // use that function to get the clIcdGetPlatformIDsKHR function pointer
97 p_clIcdGetPlatformIDs = (pfn_clIcdGetPlatformIDs)(size_t)p_clGetExtensionFunctionAddress("clIcdGetPlatformIDsKHR");
98 if (!p_clIcdGetPlatformIDs)
100 KHR_ICD_TRACE("failed to get extension function address clIcdGetPlatformIDsKHR\n");
104 // query the number of platforms available and allocate space to store them
105 result = p_clIcdGetPlatformIDs(0, NULL, &platformCount);
106 if (CL_SUCCESS != result)
108 KHR_ICD_TRACE("failed clIcdGetPlatformIDs\n");
111 platforms = (cl_platform_id *)malloc(platformCount * sizeof(cl_platform_id) );
114 KHR_ICD_TRACE("failed to allocate memory\n");
117 memset(platforms, 0, platformCount * sizeof(cl_platform_id) );
118 result = p_clIcdGetPlatformIDs(platformCount, platforms, NULL);
119 if (CL_SUCCESS != result)
121 KHR_ICD_TRACE("failed clIcdGetPlatformIDs\n");
125 // for each platform, add it
126 for (i = 0; i < platformCount; ++i)
128 KHRicdVendor* vendor = NULL;
132 // call clGetPlatformInfo on the returned platform to get the suffix
137 result = platforms[i]->dispatch->clGetPlatformInfo(
139 CL_PLATFORM_ICD_SUFFIX_KHR,
143 if (CL_SUCCESS != result)
147 suffix = (char *)malloc(suffixSize);
152 result = platforms[i]->dispatch->clGetPlatformInfo(
154 CL_PLATFORM_ICD_SUFFIX_KHR,
158 if (CL_SUCCESS != result)
164 // allocate a structure for the vendor
165 vendor = (KHRicdVendor*)malloc(sizeof(*vendor) );
169 KHR_ICD_TRACE("failed to allocate memory\n");
172 memset(vendor, 0, sizeof(*vendor) );
174 // populate vendor data
175 vendor->library = khrIcdOsLibraryLoad(libraryName);
176 if (!vendor->library)
180 KHR_ICD_TRACE("failed get platform handle to library\n");
183 vendor->clGetExtensionFunctionAddress = p_clGetExtensionFunctionAddress;
184 vendor->platform = platforms[i];
185 vendor->suffix = suffix;
187 // add this vendor to the list of vendors at the tail
189 KHRicdVendor **prevNextPointer = NULL;
190 for (prevNextPointer = &khrIcdVendors; *prevNextPointer; prevNextPointer = &( (*prevNextPointer)->next) );
191 *prevNextPointer = vendor;
194 KHR_ICD_TRACE("successfully added vendor %s with suffix %s\n", libraryName, suffix);
202 khrIcdOsLibraryUnload(library);
210 void khrIcdContextPropertiesGetPlatform(const cl_context_properties *properties, cl_platform_id *outPlatform)
212 if (properties == NULL && khrIcdVendors != NULL)
214 *outPlatform = khrIcdVendors[0].platform;
218 const cl_context_properties *property = (cl_context_properties *)NULL;
220 for (property = properties; property && property[0]; property += 2)
222 if ((cl_context_properties)CL_CONTEXT_PLATFORM == property[0])
224 *outPlatform = (cl_platform_id)property[1];