1 /* 2 * Copyright (c) 2016-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 #ifndef _ICD_H_ 20 #define _ICD_H_ 21 22 #include "icd_platform.h" 23 24 #ifndef CL_USE_DEPRECATED_OPENCL_1_0_APIS 25 #define CL_USE_DEPRECATED_OPENCL_1_0_APIS 26 #endif 27 28 #ifndef CL_USE_DEPRECATED_OPENCL_1_1_APIS 29 #define CL_USE_DEPRECATED_OPENCL_1_1_APIS 30 #endif 31 32 #ifndef CL_USE_DEPRECATED_OPENCL_1_2_APIS 33 #define CL_USE_DEPRECATED_OPENCL_1_2_APIS 34 #endif 35 36 #ifndef CL_USE_DEPRECATED_OPENCL_2_0_APIS 37 #define CL_USE_DEPRECATED_OPENCL_2_0_APIS 38 #endif 39 40 #ifndef CL_USE_DEPRECATED_OPENCL_2_1_APIS 41 #define CL_USE_DEPRECATED_OPENCL_2_1_APIS 42 #endif 43 44 #ifndef CL_USE_DEPRECATED_OPENCL_2_2_APIS 45 #define CL_USE_DEPRECATED_OPENCL_2_2_APIS 46 #endif 47 48 #include <CL/cl.h> 49 #include <CL/cl_ext.h> 50 #include <CL/cl_icd.h> 51 #include <stdio.h> 52 53 /* 54 * type definitions 55 */ 56 57 typedef cl_int (CL_API_CALL *pfn_clIcdGetPlatformIDs)( 58 cl_uint num_entries, 59 cl_platform_id *platforms, 60 cl_uint *num_platforms) CL_API_SUFFIX__VERSION_1_0; 61 62 typedef cl_int (CL_API_CALL *pfn_clGetPlatformInfo)( 63 cl_platform_id platform, 64 cl_platform_info param_name, 65 size_t param_value_size, 66 void * param_value, 67 size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; 68 69 typedef void *(CL_API_CALL *pfn_clGetExtensionFunctionAddress)( 70 const char *function_name) CL_API_SUFFIX__VERSION_1_0; 71 72 typedef struct KHRicdVendorRec KHRicdVendor; 73 74 /* 75 * KHRicdVendor 76 * 77 * Data for a single ICD vendor platform. 78 */ 79 struct KHRicdVendorRec 80 { 81 // the loaded library object (true type varies on Linux versus Windows) 82 void *library; 83 84 // the extension suffix for this platform 85 char *suffix; 86 87 // function pointer to the ICD platform IDs extracted from the library 88 pfn_clGetExtensionFunctionAddress clGetExtensionFunctionAddress; 89 90 // the platform retrieved from clGetIcdPlatformIDsKHR 91 cl_platform_id platform; 92 93 // next vendor in the list vendors 94 KHRicdVendor *next; 95 }; 96 97 // the global state 98 extern KHRicdVendor * khrIcdVendors; 99 100 extern int khrEnableTrace; 101 102 #if defined(CL_ENABLE_LAYERS) 103 /* 104 * KHRLayer 105 * 106 * Data for a single Layer 107 */ 108 struct KHRLayer; 109 struct KHRLayer 110 { 111 // the loaded library object (true type varies on Linux versus Windows) 112 void *library; 113 // the dispatch table of the layer 114 struct _cl_icd_dispatch dispatch; 115 // The next layer in the chain 116 struct KHRLayer *next; 117 #ifdef CL_LAYER_INFO 118 // The layer library name 119 char *libraryName; 120 // the pointer to the clGetLayerInfo funciton 121 void *p_clGetLayerInfo; 122 #endif 123 }; 124 125 // the global layer state 126 extern struct KHRLayer * khrFirstLayer; 127 extern struct _cl_icd_dispatch khrMasterDispatch; 128 #endif // defined(CL_ENABLE_LAYERS) 129 130 /* 131 * khrIcd interface 132 */ 133 134 // read vendors from system configuration and store the data 135 // loaded into khrIcdState. this will call the OS-specific 136 // function khrIcdEnumerateVendors. this is called at every 137 // dispatch function which may be a valid first call into the 138 // API (e.g, getPlatformIDs, etc). 139 void khrIcdInitialize(void); 140 141 // entrypoint to check and initialize trace. 142 void khrIcdInitializeTrace(void); 143 144 // go through the list of vendors (in /etc/OpenCL.conf or through 145 // the registry) and call khrIcdVendorAdd for each vendor encountered 146 // n.b, this call is OS-specific 147 void khrIcdOsVendorsEnumerateOnce(void); 148 149 // read vendors from environment variables 150 void khrIcdVendorsEnumerateEnv(void); 151 152 // add a vendor's implementation to the list of libraries 153 void khrIcdVendorAdd(const char *libraryName); 154 155 // read layers from environment variables 156 void khrIcdLayersEnumerateEnv(void); 157 158 // add a layer to the layer chain 159 void khrIcdLayerAdd(const char *libraryName); 160 161 // dynamically load a library. returns NULL on failure 162 // n.b, this call is OS-specific 163 void *khrIcdOsLibraryLoad(const char *libraryName); 164 165 // get a function pointer from a loaded library. returns NULL on failure. 166 // n.b, this call is OS-specific 167 void *khrIcdOsLibraryGetFunctionAddress(void *library, const char *functionName); 168 169 // unload a library. 170 // n.b, this call is OS-specific 171 void khrIcdOsLibraryUnload(void *library); 172 173 // parse properties and determine the platform to use from them 174 void khrIcdContextPropertiesGetPlatform( 175 const cl_context_properties *properties, 176 cl_platform_id *outPlatform); 177 178 // internal tracing macros 179 #define KHR_ICD_TRACE(...) \ 180 do \ 181 { \ 182 if (khrEnableTrace) \ 183 { \ 184 fprintf(stderr, "KHR ICD trace at %s:%d: ", __FILE__, __LINE__); \ 185 fprintf(stderr, __VA_ARGS__); \ 186 } \ 187 } while (0) 188 189 #ifdef _WIN32 190 #define KHR_ICD_WIDE_TRACE(...) \ 191 do \ 192 { \ 193 if (khrEnableTrace) \ 194 { \ 195 fwprintf(stderr, L"KHR ICD trace at %hs:%d: ", __FILE__, __LINE__); \ 196 fwprintf(stderr, __VA_ARGS__); \ 197 } \ 198 } while (0) 199 200 #else 201 #define KHR_ICD_WIDE_TRACE(...) 202 #endif 203 204 // Check if the passed-in handle is NULL, and if it is, return the error. 205 #define KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(_handle, _error) \ 206 do { \ 207 if (!_handle) { \ 208 return _error; \ 209 } \ 210 } while (0) 211 212 // Check if the passed-in handle is NULL, and if it is, first check and set 213 // errcode_ret to the error, then return NULL (NULL being an invalid handle). 214 #define KHR_ICD_VALIDATE_HANDLE_RETURN_HANDLE(_handle, _error) \ 215 do { \ 216 if (!_handle) { \ 217 if (errcode_ret) { \ 218 *errcode_ret = _error; \ 219 } \ 220 return NULL; \ 221 } \ 222 } while (0) 223 224 // Check if the passed-in function pointer is NULL, and if it is, return 225 // CL_INVALID_OPERATION. 226 #define KHR_ICD_VALIDATE_POINTER_RETURN_ERROR(_pointer) \ 227 do { \ 228 if (!_pointer) { \ 229 return CL_INVALID_OPERATION; \ 230 } \ 231 } while (0) 232 233 // Check if the passed-in function pointer is NULL, and if it is, first 234 // check and set errcode_ret to CL_INVALID_OPERATION, then return NULL 235 // (NULL being an invalid handle). 236 #define KHR_ICD_VALIDATE_POINTER_RETURN_HANDLE(_pointer) \ 237 do { \ 238 if (!_pointer) { \ 239 if (errcode_ret) { \ 240 *errcode_ret = CL_INVALID_OPERATION; \ 241 } \ 242 return NULL; \ 243 } \ 244 } while (0) 245 246 #endif 247