diff --git a/icd_generator.rb b/icd_generator.rb index c06c2b5..31ee34d 100644 --- a/icd_generator.rb +++ b/icd_generator.rb @@ -542,20 +542,15 @@ def self.generate_ocl_icd_loader_header clGetExtensionFunctionAddress_fn ext_fn_ptr; }; -struct platform_icd { - char * extension_suffix; - char * version; - struct vendor_icd *vicd; - cl_platform_id pid; - cl_uint ngpus; /* number of GPU devices */ - cl_uint ncpus; /* number of CPU devices */ - cl_uint ndevs; /* total number of devices, of all types */ -}; - +extern struct _cl_icd_dispatch master_dispatch; EOF - ocl_icd_header += "extern struct _cl_icd_dispatch master_dispatch;\n" $cl_objects.each { |o| - ocl_icd_header += "struct _cl_#{o} { struct _cl_icd_dispatch *dispatch; };\n" + ocl_icd_header += <#{e} = (typeof(#{e})*)pltfn_fn_ptr(pid, "#{e}"); + if (!dispatch->#{e}) + dispatch->#{e} = #{e}_unsupp; +EOF + else + ocl_icd_loader_gen_source << " dispatch->clUnknown#{i} = NULL;\n" + end + } + + ocl_icd_loader_gen_source << <ngpus = p->ncpus = p->ndevs = 0; - error = p->pid->dispatch->clGetDeviceIDs(p->pid, CL_DEVICE_TYPE_GPU, 0, NULL, &(p->ngpus)); + error = KHR_ICD2_DISPATCH(p->pid)->clGetDeviceIDs(p->pid, CL_DEVICE_TYPE_GPU, 0, NULL, &(p->ngpus)); if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND){ debug(D_WARN, "Error %s while counting GPU devices in platform %p", _clerror2string(error), p->pid); } - error = p->pid->dispatch->clGetDeviceIDs(p->pid, CL_DEVICE_TYPE_CPU, 0, NULL, &(p->ncpus)); + error = KHR_ICD2_DISPATCH(p->pid)->clGetDeviceIDs(p->pid, CL_DEVICE_TYPE_CPU, 0, NULL, &(p->ncpus)); if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND){ debug(D_WARN, "Error %s while counting CPU devices in platform %p", _clerror2string(error), p->pid); } - error = p->pid->dispatch->clGetDeviceIDs(p->pid, CL_DEVICE_TYPE_ALL, 0, NULL, &(p->ndevs)); + error = KHR_ICD2_DISPATCH(p->pid)->clGetDeviceIDs(p->pid, CL_DEVICE_TYPE_ALL, 0, NULL, &(p->ndevs)); if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND){ debug(D_WARN, "Error %s while counting ALL devices in platform %p", _clerror2string(error), p->pid); @@ -496,6 +496,11 @@ static inline void _find_and_check_platforms(cl_uint num_icds) { debug(D_WARN, "Not enough platform allocated. Skipping ICD"); continue; } + clIcdGetFunctionAddressForPlatformKHR_fn pltfn_fn_ptr = + _get_function_addr(dlh, picd->ext_fn_ptr, "clIcdGetFunctionAddressForPlatformKHR"); + clIcdSetPlatformDispatchDataKHR_fn spltdd_fn_ptr = + _get_function_addr(dlh, picd->ext_fn_ptr, "clIcdSetPlatformDispatchDataKHR"); + for(j=0; jvicd=&_icds[i]; p->pid=platforms[j]; + if (KHR_ICD2_HAS_TAG(p->pid) && !pltfn_fn_ptr) { + debug(D_WARN, "Found icd 2 platform, but it is missing clIcdGetFunctionAddressForPlatformKHR, skipping it"); + continue; + } + + if (KHR_ICD2_HAS_TAG(p->pid) && !spltdd_fn_ptr) { + debug(D_WARN, "Found icd 2 platform, but it is missing clIcdSetPlatformDispatchDataKHR, skipping it"); + continue; + } + + if (KHR_ICD2_HAS_TAG(p->pid) && !(((size_t)((p->pid)->dispatch->clUnloadCompiler)) == CL_ICD2_TAG_KHR)) { + debug(D_WARN, "Found icd 2 platform, but it is missing clUnloadCompiler tag, skipping it"); + continue; + } + + if (KHR_ICD2_HAS_TAG(p->pid)) + { + _populate_dispatch_table(p->pid, pltfn_fn_ptr, &p->disp_data.dispatch); + spltdd_fn_ptr(p->pid, &p->disp_data); + debug(D_LOG, "Found icd 2 platform, using loader managed dispatch"); + } + /* If clGetPlatformInfo is not exported and we are here, it * means that OCL_ICD_ASSUME_ICD_EXTENSION. Si we try to take it * from the dispatch * table. If that fails too, we have to * bail. */ if (plt_info_ptr == NULL) { - plt_info_ptr = p->pid->dispatch->clGetPlatformInfo; + plt_info_ptr = KHR_ICD2_DISPATCH(p->pid)->clGetPlatformInfo; if (plt_info_ptr == NULL) { debug(D_WARN, "Missing clGetPlatformInfo even in ICD dispatch table, skipping it"); continue; @@ -1176,8 +1203,8 @@ hidden_alias(clGetPlatformIDs); RETURN_WITH_ERRCODE(errcode_ret, CL_INVALID_PLATFORM, NULL); \ } \ } \ - RETURN(((struct _cl_platform_id *) properties[i+1]) \ - ->dispatch->clCreateContext(properties, num_devices, devices, \ + RETURN(KHR_ICD2_DISPATCH((struct _cl_platform_id *) properties[i+1]) \ + ->clCreateContext(properties, num_devices, devices, \ pfn_notify, user_data, errcode_ret)); \ } \ i += 2; \ @@ -1189,8 +1216,8 @@ hidden_alias(clGetPlatformIDs); if((struct _cl_device_id *)devices[0] == NULL) { \ RETURN_WITH_ERRCODE(errcode_ret, CL_INVALID_DEVICE, NULL); \ } \ - RETURN(((struct _cl_device_id *)devices[0]) \ - ->dispatch->clCreateContext(properties, num_devices, devices, \ + RETURN(KHR_ICD2_DISPATCH((struct _cl_device_id *)devices[0]) \ + ->clCreateContext(properties, num_devices, devices, \ pfn_notify, user_data, errcode_ret)); @@ -1239,15 +1266,15 @@ hidden_alias(clCreateContext); goto out; \ } \ } \ - return ((struct _cl_platform_id *) properties[i+1]) \ - ->dispatch->clCreateContextFromType(properties, device_type, \ + return KHR_ICD2_DISPATCH((struct _cl_platform_id *) properties[i+1]) \ + ->clCreateContextFromType(properties, device_type, \ pfn_notify, user_data, errcode_ret); \ } \ i += 2; \ } \ } else { \ cl_platform_id default_platform=getDefaultPlatformID(); \ - RETURN(default_platform->dispatch->clCreateContextFromType \ + RETURN(KHR_ICD2_DISPATCH(default_platform)->clCreateContextFromType \ (properties, device_type, pfn_notify, user_data, errcode_ret)); \ } \ out: \ @@ -1292,8 +1319,8 @@ hidden_alias(clCreateContextFromType); RETURN(CL_INVALID_PLATFORM); \ } \ } \ - RETURN(((struct _cl_platform_id *) properties[i+1]) \ - ->dispatch->clGetGLContextInfoKHR(properties, param_name, \ + RETURN(KHR_ICD2_DISPATCH((struct _cl_platform_id *) properties[i+1]) \ + ->clGetGLContextInfoKHR(properties, param_name, \ param_value_size, param_value, param_value_size_ret)); \ } \ i += 2; \ @@ -1333,8 +1360,8 @@ hidden_alias(clGetGLContextInfoKHR); RETURN(CL_INVALID_VALUE); \ if( (struct _cl_event *)event_list[0] == NULL ) \ RETURN(CL_INVALID_EVENT); \ - RETURN(((struct _cl_event *)event_list[0]) \ - ->dispatch->clWaitForEvents(num_events, event_list)); + RETURN(KHR_ICD2_DISPATCH((struct _cl_event *)event_list[0]) \ + ->clWaitForEvents(num_events, event_list)); __attribute__ ((visibility ("hidden"))) cl_int clWaitForEvents_disp(cl_uint num_events, diff --git a/ocl_icd_loader.h b/ocl_icd_loader.h index 6ebc823..55d77fe 100644 --- a/ocl_icd_loader.h +++ b/ocl_icd_loader.h @@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ocl_icd.h" #include "ocl_icd_loader_gen.h" +#include cl_platform_id __attribute__((visibility("internal"))) getDefaultPlatformID(); @@ -73,6 +74,58 @@ struct layer_icd { #endif }; -__attribute__((visibility("hidden"))) extern struct layer_icd *_first_layer; + +#ifndef CL_ICD2_TAG_KHR +#define CL_ICD2_TAG_KHR ((size_t)0x4F50454E434C3331ULL) + +typedef void * CL_API_CALL +clIcdGetFunctionAddressForPlatformKHR_t( + cl_platform_id platform, + const char* function_name); + +typedef clIcdGetFunctionAddressForPlatformKHR_t * +clIcdGetFunctionAddressForPlatformKHR_fn; + +typedef cl_int CL_API_CALL +clIcdSetPlatformDispatchDataKHR_t( + cl_platform_id platform, + void *disp_data); + +typedef clIcdSetPlatformDispatchDataKHR_t * +clIcdSetPlatformDispatchDataKHR_fn; + +__attribute__((visibility("hidden"))) +extern void _populate_dispatch_table( + cl_platform_id platform, + clIcdGetFunctionAddressForPlatformKHR_fn pltfn_fn_ptr, + struct _cl_icd_dispatch* dispatch); +#endif + +struct _cl_disp_data +{ + struct _cl_icd_dispatch dispatch; +}; + +#define KHR_ICD2_HAS_TAG(object) \ +(((size_t)((object)->dispatch->clGetPlatformIDs)) == CL_ICD2_TAG_KHR) + +#define KHR_ICD2_DISPATCH(object) \ +(KHR_ICD2_HAS_TAG(object) ? \ + &(object)->disp_data->dispatch : \ + (object)->dispatch) + +struct platform_icd { + char *extension_suffix; + char *version; + struct vendor_icd *vicd; + cl_platform_id pid; + cl_uint ngpus; /* number of GPU devices */ + cl_uint ncpus; /* number of CPU devices */ + cl_uint ndevs; /* total number of devices, of all types */ + struct _cl_disp_data disp_data; +}; + +__attribute__((visibility("hidden"))) +extern struct layer_icd *_first_layer; #endif