xref: /aosp_15_r20/external/OpenCL-ICD-Loader/loader/icd_dispatch.c (revision 1cddb830dba8aa7c1cc1039338e56b3b9fa24952)
1 /*
2  * Copyright (c) 2012-2020 The Khronos Group Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * OpenCL is a trademark of Apple Inc. used under license by Khronos.
17  */
18 
19 #include "icd.h"
20 #include "icd_dispatch.h"
21 #include "icd_version.h"
22 
23 #include <stdlib.h>
24 #include <string.h>
25 
26 static clGetICDLoaderInfoOCLICD_t clGetICDLoaderInfoOCLICD;
27 cl_int CL_API_CALL
clGetICDLoaderInfoOCLICD(cl_icdl_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)28 clGetICDLoaderInfoOCLICD(
29     cl_icdl_info param_name,
30     size_t       param_value_size,
31     void *       param_value,
32     size_t *     param_value_size_ret)
33 {
34     static const char cl_icdl_OCL_VERSION[] = OPENCL_ICD_LOADER_OCL_VERSION_STRING;
35     static const char cl_icdl_VERSION[]     = OPENCL_ICD_LOADER_VERSION_STRING;
36     static const char cl_icdl_NAME[]        = OPENCL_ICD_LOADER_NAME_STRING;
37     static const char cl_icdl_VENDOR[]      = OPENCL_ICD_LOADER_VENDOR_STRING;
38     size_t            pvs;
39     void *            pv;
40 
41 #define KHR_ICD_CASE_STRING_PARAM_NAME(name)                                   \
42     case CL_ICDL_ ## name:                                                     \
43         pvs = strlen(cl_icdl_ ## name) + 1;                                    \
44         pv = (void *)cl_icdl_ ## name;                                         \
45         break
46 
47     switch (param_name) {
48     KHR_ICD_CASE_STRING_PARAM_NAME(OCL_VERSION);
49     KHR_ICD_CASE_STRING_PARAM_NAME(VERSION);
50     KHR_ICD_CASE_STRING_PARAM_NAME(NAME);
51     KHR_ICD_CASE_STRING_PARAM_NAME(VENDOR);
52     default:
53         return CL_INVALID_VALUE;
54     }
55 
56 #undef KHR_ICD_CASE_PARAM_NAME
57 
58     if (param_value) {
59         if (param_value_size < pvs)
60             return CL_INVALID_VALUE;
61         memcpy(param_value, pv, pvs);
62     }
63     if (param_value_size_ret != NULL)
64         *param_value_size_ret = pvs;
65     return CL_SUCCESS;
66 }
67 
khrIcdGetExtensionFunctionAddress(const char * function_name)68 static void* khrIcdGetExtensionFunctionAddress(const char* function_name)
69 {
70 // Most extensions, including multi-vendor KHR and EXT extensions,
71 // do not need to be ICD-aware and do not require any ICD loader
72 // modifications.  The KHR and EXT extensions below were added for
73 // backwards compatibility only.
74 #define KHR_ICD_CHECK_EXTENSION_FUNCTION(name)                                 \
75     do                                                                         \
76     {                                                                          \
77         if (!strcmp(function_name, #name))                                     \
78         {                                                                      \
79             return (void*)(size_t)&name;                                       \
80         }                                                                      \
81     } while (0)
82 
83     // Functions supporting the creation of OpenCL Memory Objects
84     // from OpenGL Objects (cl_apple_gl_sharing, cl_khr_gl_sharing)
85     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromGLBuffer);
86     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromGLTexture);
87     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromGLTexture2D);
88     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromGLTexture3D);
89     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromGLRenderbuffer);
90     KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetGLObjectInfo);
91     KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetGLTextureInfo);
92     KHR_ICD_CHECK_EXTENSION_FUNCTION(clEnqueueAcquireGLObjects);
93     KHR_ICD_CHECK_EXTENSION_FUNCTION(clEnqueueReleaseGLObjects);
94 
95     // cl_khr_gl_sharing
96     KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetGLContextInfoKHR);
97 
98     // cl_khr_gl_event
99     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateEventFromGLsyncKHR);
100 
101 #if defined(_WIN32)
102     // cl_khr_d3d10_sharing
103     KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetDeviceIDsFromD3D10KHR);
104     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromD3D10BufferKHR);
105     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromD3D10Texture2DKHR);
106     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromD3D10Texture3DKHR);
107     KHR_ICD_CHECK_EXTENSION_FUNCTION(clEnqueueAcquireD3D10ObjectsKHR);
108     KHR_ICD_CHECK_EXTENSION_FUNCTION(clEnqueueReleaseD3D10ObjectsKHR);
109     // cl_khr_d3d11_sharing
110     KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetDeviceIDsFromD3D11KHR);
111     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromD3D11BufferKHR);
112     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromD3D11Texture2DKHR);
113     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromD3D11Texture3DKHR);
114     KHR_ICD_CHECK_EXTENSION_FUNCTION(clEnqueueAcquireD3D11ObjectsKHR);
115     KHR_ICD_CHECK_EXTENSION_FUNCTION(clEnqueueReleaseD3D11ObjectsKHR);
116     // cl_khr_dx9_media_sharing
117     KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetDeviceIDsFromDX9MediaAdapterKHR);
118     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromDX9MediaSurfaceKHR);
119     KHR_ICD_CHECK_EXTENSION_FUNCTION(clEnqueueAcquireDX9MediaSurfacesKHR);
120     KHR_ICD_CHECK_EXTENSION_FUNCTION(clEnqueueReleaseDX9MediaSurfacesKHR);
121 #endif
122 
123     // cl_ext_device_fission
124     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateSubDevicesEXT);
125     KHR_ICD_CHECK_EXTENSION_FUNCTION(clRetainDeviceEXT);
126     KHR_ICD_CHECK_EXTENSION_FUNCTION(clReleaseDeviceEXT);
127 
128     // cl_khr_egl_image
129     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateFromEGLImageKHR);
130     KHR_ICD_CHECK_EXTENSION_FUNCTION(clEnqueueAcquireEGLObjectsKHR);
131     KHR_ICD_CHECK_EXTENSION_FUNCTION(clEnqueueReleaseEGLObjectsKHR);
132 
133     // cl_khr_egl_event
134     KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateEventFromEGLSyncKHR);
135 
136     // cl_khr_sub_groups
137     KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetKernelSubGroupInfoKHR);
138 
139     // cl_icdl
140     KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetICDLoaderInfoOCLICD);
141 
142 #undef KHR_ICD_CHECK_EXTENSION_FUNCTION
143 
144     return NULL;
145 }
146 
147 #ifdef __cplusplus
148 extern "C" {
149 #endif
150 
clGetPlatformIDs_body(cl_uint num_entries,cl_platform_id * platforms,cl_uint * num_platforms)151 static inline cl_int clGetPlatformIDs_body(
152     cl_uint num_entries,
153     cl_platform_id* platforms,
154     cl_uint* num_platforms)
155 {
156     KHRicdVendor* vendor = NULL;
157     cl_uint i;
158 
159     if (!num_entries && platforms)
160     {
161         return CL_INVALID_VALUE;
162     }
163     if (!platforms && !num_platforms)
164     {
165         return CL_INVALID_VALUE;
166     }
167     // set num_platforms to 0 and set all platform pointers to NULL
168     if (num_platforms)
169     {
170         *num_platforms = 0;
171     }
172     for (i = 0; i < num_entries && platforms; ++i)
173     {
174         platforms[i] = NULL;
175     }
176     // return error if we have no platforms
177     if (!khrIcdVendors)
178     {
179         return CL_PLATFORM_NOT_FOUND_KHR;
180     }
181     // otherwise enumerate all platforms
182     for (vendor = khrIcdVendors; vendor; vendor = vendor->next)
183     {
184         if (num_entries && platforms)
185         {
186             *(platforms++) = vendor->platform;
187             --num_entries;
188         }
189         if (num_platforms)
190         {
191             ++(*num_platforms);
192         }
193     }
194     return CL_SUCCESS;
195 }
196 
clGetPlatformIDs_disp(cl_uint num_entries,cl_platform_id * platforms,cl_uint * num_platforms)197 cl_int CL_API_CALL clGetPlatformIDs_disp(
198     cl_uint num_entries,
199     cl_platform_id* platforms,
200     cl_uint* num_platforms)
201 {
202     return clGetPlatformIDs_body(
203         num_entries,
204         platforms,
205         num_platforms);
206 }
207 
clGetPlatformIDs(cl_uint num_entries,cl_platform_id * platforms,cl_uint * num_platforms)208 CL_API_ENTRY cl_int CL_API_CALL clGetPlatformIDs(
209     cl_uint num_entries,
210     cl_platform_id* platforms,
211     cl_uint* num_platforms)
212 {
213     // initialize the platforms (in case they have not been already)
214     khrIcdInitialize();
215 
216 #if defined(CL_ENABLE_LAYERS)
217     if (khrFirstLayer)
218         return khrFirstLayer->dispatch.clGetPlatformIDs(
219             num_entries,
220             platforms,
221             num_platforms);
222 #endif // defined(CL_ENABLE_LAYERS)
223     return clGetPlatformIDs_body(
224         num_entries,
225         platforms,
226         num_platforms);
227 }
228 
clGetExtensionFunctionAddress_body(const char * function_name)229 static inline void* clGetExtensionFunctionAddress_body(
230     const char* function_name)
231 {
232     void* function_address = NULL;
233     size_t function_name_length = 0;
234     KHRicdVendor* vendor = NULL;
235 
236     KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(function_name, NULL);
237 
238     // check if this is an ICD-aware extension
239     function_address = khrIcdGetExtensionFunctionAddress(function_name);
240     if (function_address)
241     {
242         return function_address;
243     }
244 
245     // fall back to vendor extension detection
246     function_name_length = strlen(function_name);
247     for (vendor = khrIcdVendors; vendor; vendor = vendor->next)
248     {
249         size_t vendor_suffix_length = strlen(vendor->suffix);
250         if (vendor_suffix_length <= function_name_length &&
251             vendor_suffix_length > 0)
252         {
253             const char* function_suffix =
254                 function_name + function_name_length - vendor_suffix_length;
255             if (!strcmp(function_suffix, vendor->suffix))
256             {
257                 return vendor->clGetExtensionFunctionAddress(function_name);
258             }
259         }
260     }
261 
262     return NULL;
263 }
264 
clGetExtensionFunctionAddress_disp(const char * function_name)265 void* CL_API_CALL clGetExtensionFunctionAddress_disp(
266     const char* function_name)
267 {
268     return clGetExtensionFunctionAddress_body(
269         function_name);
270 }
271 
clGetExtensionFunctionAddress(const char * function_name)272 CL_API_ENTRY void* CL_API_CALL clGetExtensionFunctionAddress(
273     const char* function_name)
274 {
275     // make sure the ICD is initialized
276     khrIcdInitialize();
277 
278 #if defined(CL_ENABLE_LAYERS)
279     if (khrFirstLayer)
280         return khrFirstLayer->dispatch.clGetExtensionFunctionAddress(
281             function_name);
282 #endif // defined(CL_ENABLE_LAYERS)
283     return clGetExtensionFunctionAddress_body(
284         function_name);
285 }
286 
clGetExtensionFunctionAddressForPlatform_body(cl_platform_id platform,const char * function_name)287 static inline void* clGetExtensionFunctionAddressForPlatform_body(
288     cl_platform_id platform,
289     const char* function_name)
290 {
291     void* function_address = NULL;
292 
293     KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(function_name, NULL);
294 
295     // check if this is an ICD-aware extension
296     function_address = khrIcdGetExtensionFunctionAddress(function_name);
297     if (function_address)
298     {
299         return function_address;
300     }
301 
302     // This is not an ICD-aware extension, so call into the implementation
303     // to get the extension function address.
304 
305     KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(platform, NULL);
306     return platform->dispatch->clGetExtensionFunctionAddressForPlatform(
307         platform,
308         function_name);
309 }
310 
clGetExtensionFunctionAddressForPlatform_disp(cl_platform_id platform,const char * function_name)311 void* CL_API_CALL clGetExtensionFunctionAddressForPlatform_disp(
312     cl_platform_id platform,
313     const char* function_name)
314 {
315     return clGetExtensionFunctionAddressForPlatform_body(
316         platform,
317         function_name);
318 }
319 
clGetExtensionFunctionAddressForPlatform(cl_platform_id platform,const char * function_name)320 CL_API_ENTRY void* CL_API_CALL clGetExtensionFunctionAddressForPlatform(
321     cl_platform_id platform,
322     const char* function_name)
323 {
324     // make sure the ICD is initialized
325     khrIcdInitialize();
326 #if defined(CL_ENABLE_LAYERS)
327     if (khrFirstLayer)
328         return khrFirstLayer->dispatch.clGetExtensionFunctionAddressForPlatform(
329             platform,
330             function_name);
331 #endif // defined(CL_ENABLE_LAYERS)
332     return clGetExtensionFunctionAddressForPlatform_body(
333         platform,
334         function_name);
335 }
336 
337 #ifdef __cplusplus
338 }
339 #endif
340