Signed-off-by: Nakarin Khankham garuda2550@gmail.com --- configure | 56 ++++++++ configure.ac | 1 + dlls/opencl/opencl.c | 321 +++++++++++++++++++++++++++++++++++++++++++ include/config.h.in | 3 + 4 files changed, 381 insertions(+)
diff --git a/configure b/configure index 5f9aca9bd4..8e4ccc8209 100755 --- a/configure +++ b/configure @@ -11809,6 +11809,62 @@ if test "x$ac_cv_lib_OpenCL_clGetPlatformInfo" = xyes; then :
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -lOpenCL" >&5 +$as_echo_n "checking for -lOpenCL... " >&6; } +if ${ac_cv_lib_soname_OpenCL+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_soname_save_LIBS=$LIBS +LIBS="-lOpenCL $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clGetPlatformInfo (); +int +main () +{ +return clGetPlatformInfo (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + case "$LIBEXT" in + dll) ac_cv_lib_soname_OpenCL=`$ac_cv_path_LDD conftest.exe | grep "OpenCL" | sed -e "s/dll.*/dll/"';2,$d'` ;; + dylib) ac_cv_lib_soname_OpenCL=`$OTOOL -L conftest$ac_exeext | grep "libOpenCL\.[0-9A-Za-z.]*dylib" | sed -e "s/^.*/(libOpenCL.[0-9A-Za-z.]*dylib).*$/\1/"';2,$d'` ;; + *) ac_cv_lib_soname_OpenCL=`$READELF -d conftest$ac_exeext | grep "NEEDED.*libOpenCL\.$LIBEXT" | sed -e "s/^.*\[\(libOpenCL\.$LIBEXT[^ ]*\)\].*$/\1/"';2,$d'` + if ${ac_cv_lib_soname_OpenCL:+false} :; then : + ac_cv_lib_soname_OpenCL=`$LDD conftest$ac_exeext | grep "libOpenCL\.$LIBEXT" | sed -e "s/^.*(libOpenCL.$LIBEXT[^ ]*).*$/\1/"';2,$d'` +fi ;; + esac +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_check_soname_save_LIBS +fi +if ${ac_cv_lib_soname_OpenCL:+false} :; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } + cat >>confdefs.h <<_ACEOF +#define SONAME_LIBOPENCL "libOpenCL.$LIBEXT" +_ACEOF + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_soname_OpenCL" >&5 +$as_echo "$ac_cv_lib_soname_OpenCL" >&6; } + +cat >>confdefs.h <<_ACEOF +#define SONAME_LIBOPENCL "$ac_cv_lib_soname_OpenCL" +_ACEOF + + +fi fi if test "x$ac_cv_lib_OpenCL_clGetPlatformInfo" != xyes; then : case "x$with_opencl" in diff --git a/configure.ac b/configure.ac index a55d2f825a..8c8bbc1704 100644 --- a/configure.ac +++ b/configure.ac @@ -1264,6 +1264,7 @@ dnl **** Check for OpenCL **** if test "$ac_cv_header_CL_cl_h" = "yes" then AC_CHECK_LIB(OpenCL,clGetPlatformInfo,[AC_SUBST(OPENCL_LIBS,["-lOpenCL"])]) + WINE_CHECK_SONAME(OpenCL,clGetPlatformInfo,,[AC_DEFINE_UNQUOTED(SONAME_LIBOPENCL,["libOpenCL.$LIBEXT"])]) fi WINE_NOTICE_WITH(opencl,[test "x$ac_cv_lib_OpenCL_clGetPlatformInfo" != xyes], [OpenCL ${notice_platform}development files not found, OpenCL won't be supported.], diff --git a/dlls/opencl/opencl.c b/dlls/opencl/opencl.c index 2d145bf25c..ad781b92b5 100644 --- a/dlls/opencl/opencl.c +++ b/dlls/opencl/opencl.c @@ -43,6 +43,327 @@ WINE_DEFAULT_DEBUG_CHANNEL(opencl); #define OPENCL_WITH_GL 0
+/* Platform API */ +static cl_int (*pclGetPlatformIDs)(cl_uint num_entries, cl_platform_id *platforms, cl_uint *num_platforms); +static cl_int (*pclGetPlatformInfo)(cl_platform_id platform, cl_platform_info param_name, + SIZE_T param_value_size, void * param_value, size_t * param_value_size_ret); + +/* Device APIs */ +static cl_int (*pclGetDeviceIDs)(cl_platform_id platform, cl_device_type device_type, + cl_uint num_entries, cl_device_id * devices, cl_uint * num_devices); +static cl_int (*pclGetDeviceInfo)(cl_device_id device, cl_device_info param_name, + SIZE_T param_value_size, void * param_value, size_t * param_value_size_ret); + +/* Context APIs */ +static cl_context (*pclCreateContext)(const cl_context_properties * properties, cl_uint num_devices, const cl_device_id * devices, + void WINAPI (*pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data), + void * user_data, cl_int * errcode_ret); +static cl_context (*pclCreateContextFromType)(const cl_context_properties * properties, cl_device_type device_type, + void WINAPI (*pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data), + void * user_data, cl_int * errcode_ret); +static cl_int (*pclRetainContext)(cl_context context); +static cl_int (*pclReleaseContext)(cl_context context); +static cl_int (*pclGetContextInfo)(cl_context context, cl_context_info param_name, + SIZE_T param_value_size, void * param_value, size_t * param_value_size_ret); + +/* Command Queue APIs */ +static cl_command_queue (*pclCreateCommandQueue)(cl_context context, cl_device_id device, + cl_command_queue_properties properties, cl_int * errcode_ret); +static cl_int (*pclRetainCommandQueue)(cl_command_queue command_queue); +static cl_int (*pclReleaseCommandQueue)(cl_command_queue command_queue); +static cl_int (*pclGetCommandQueueInfo)(cl_command_queue command_queue, cl_command_queue_info param_name, + SIZE_T param_value_size, void * param_value, size_t * param_value_size_ret); +static cl_int (*pclSetCommandQueueProperty)(cl_command_queue command_queue, cl_command_queue_properties properties, cl_bool enable, + cl_command_queue_properties * old_properties); + +/* Memory Object APIs */ +static cl_mem (*pclCreateBuffer)(cl_context context, cl_mem_flags flags, size_t size, void * host_ptr, cl_int * errcode_ret); +static cl_mem (*pclCreateImage2D)(cl_context context, cl_mem_flags flags, cl_image_format * image_format, + size_t image_width, size_t image_height, size_t image_row_pitch, void * host_ptr, cl_int * errcode_ret); +static cl_mem (*pclCreateImage3D)(cl_context context, cl_mem_flags flags, cl_image_format * image_format, + size_t image_width, size_t image_height, size_t image_depth, size_t image_row_pitch, size_t image_slice_pitch, + void * host_ptr, cl_int * errcode_ret); +static cl_int (*pclRetainMemObject)(cl_mem memobj); +static cl_int (*pclReleaseMemObject)(cl_mem memobj); +static cl_int (*pclGetSupportedImageFormats)(cl_context context, cl_mem_flags flags, cl_mem_object_type image_type, cl_uint num_entries, + cl_image_format * image_formats, cl_uint * num_image_formats); +static cl_int (*pclGetMemObjectInfo)(cl_mem memobj, cl_mem_info param_name, size_t param_value_size, void * param_value, size_t * param_value_size_ret); +static cl_int (*pclGetImageInfo)(cl_mem image, cl_image_info param_name, size_t param_value_size, void * param_value, size_t * param_value_size_ret); + +/* Sampler APIs */ +static cl_sampler (*pclCreateSampler)(cl_context context, cl_bool normalized_coords, cl_addressing_mode addressing_mode, + cl_filter_mode filter_mode, cl_int * errcode_ret); +static cl_int (*pclRetainSampler)(cl_sampler sampler); +static cl_int (*pclReleaseSampler)(cl_sampler sampler); +static cl_int (*pclGetSamplerInfo)(cl_sampler sampler, cl_sampler_info param_name, size_t param_value_size, + void * param_value, size_t * param_value_size_ret); + +/* Program Object APIs */ +static cl_program (*pclCreateProgramWithSource)(cl_context context, cl_uint count, const char ** strings, + const size_t * lengths, cl_int * errcode_ret); +static cl_program (*pclCreateProgramWithBinary)(cl_context context, cl_uint num_devices, const cl_device_id * device_list, + const size_t * lengths, const unsigned char ** binaries, cl_int * binary_status, + cl_int * errcode_ret); +static cl_int (*pclRetainProgram)(cl_program program); +static cl_int (*pclReleaseProgram)(cl_program program); +static cl_int (*pclBuildProgram)(cl_program program, cl_uint num_devices, const cl_device_id * device_list, const char * options, + void WINAPI (*pfn_notify)(cl_program program, void * user_data), + void * user_data); +static cl_int (*pclUnloadCompiler)(void); +static cl_int (*pclGetProgramInfo)(cl_program program, cl_program_info param_name, + size_t param_value_size, void * param_value, size_t * param_value_size_ret); +static cl_int (*pclGetProgramBuildInfo)(cl_program program, cl_device_id device, + cl_program_build_info param_name, size_t param_value_size, void * param_value, + size_t * param_value_size_ret); + +/* Kernel Object APIs */ +static cl_kernel (*pclCreateKernel)(cl_program program, char * kernel_name, cl_int * errcode_ret); +static cl_int (*pclCreateKernelsInProgram)(cl_program program, cl_uint num_kernels, + cl_kernel * kernels, cl_uint * num_kernels_ret); +static cl_int (*pclRetainKernel)(cl_kernel kernel); +static cl_int (*pclReleaseKernel)(cl_kernel kernel); +static cl_int (*pclSetKernelArg)(cl_kernel kernel, cl_uint arg_index, size_t arg_size, void * arg_value); +static cl_int (*pclGetKernelInfo)(cl_kernel kernel, cl_kernel_info param_name, + size_t param_value_size, void * param_value, size_t * param_value_size_ret); +static cl_int (*pclGetKernelWorkGroupInfo)(cl_kernel kernel, cl_device_id device, + cl_kernel_work_group_info param_name, size_t param_value_size, + void * param_value, size_t * param_value_size_ret); +/* Event Object APIs */ +static cl_int (*pclWaitForEvents)(cl_uint num_events, cl_event * event_list); +static cl_int (*pclGetEventInfo)(cl_event event, cl_event_info param_name, size_t param_value_size, + void * param_value, size_t * param_value_size_ret); +static cl_int (*pclRetainEvent)(cl_event event); +static cl_int (*pclReleaseEvent)(cl_event event); + +/* Profiling APIs */ +static cl_int (*pclGetEventProfilingInfo)(cl_event event, cl_profiling_info param_name, size_t param_value_size, + void * param_value, size_t * param_value_size_ret); + +/* Flush and Finish APIs */ +static cl_int (*pclFlush)(cl_command_queue command_queue); +static cl_int (*pclFinish)(cl_command_queue command_queue); + +/* Enqueued Commands APIs */ +static cl_int (*pclEnqueueReadBuffer)(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, + size_t offset, size_t cb, void * ptr, + cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event); +static cl_int (*pclEnqueueWriteBuffer)(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_write, + size_t offset, size_t cb, const void * ptr, + cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event); +static cl_int (*pclEnqueueCopyBuffer)(cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_buffer, + size_t src_offset, size_t dst_offset, size_t cb, + cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event); +static cl_int (*pclEnqueueReadImage)(cl_command_queue command_queue, cl_mem image, cl_bool blocking_read, + const size_t * origin, const size_t * region, + SIZE_T row_pitch, SIZE_T slice_pitch, void * ptr, + cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event); +static cl_int (*pclEnqueueWriteImage)(cl_command_queue command_queue, cl_mem image, cl_bool blocking_write, + const size_t * origin, const size_t * region, + size_t input_row_pitch, size_t input_slice_pitch, const void * ptr, + cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event); +static cl_int (*pclEnqueueCopyImage)(cl_command_queue command_queue, cl_mem src_image, cl_mem dst_image, + size_t * src_origin, size_t * dst_origin, size_t * region, + cl_uint num_events_in_wait_list, cl_event * event_wait_list, cl_event * event); +static cl_int (*pclEnqueueCopyImageToBuffer)(cl_command_queue command_queue, cl_mem src_image, cl_mem dst_buffer, + size_t * src_origin, size_t * region, size_t dst_offset, + cl_uint num_events_in_wait_list, cl_event * event_wait_list, cl_event * event); +static cl_int (*pclEnqueueCopyBufferToImage)(cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_image, + size_t src_offset, size_t * dst_origin, size_t * region, + cl_uint num_events_in_wait_list, cl_event * event_wait_list, cl_event * event); +static void * (*pclEnqueueMapBuffer)(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_map, + cl_map_flags map_flags, size_t offset, size_t cb, + cl_uint num_events_in_wait_list, cl_event * event_wait_list, cl_event * event, cl_int * errcode_ret); +static void * (*pclEnqueueMapImage)(cl_command_queue command_queue, cl_mem image, cl_bool blocking_map, + cl_map_flags map_flags, size_t * origin, size_t * region, + size_t * image_row_pitch, size_t * image_slice_pitch, + cl_uint num_events_in_wait_list, cl_event * event_wait_list, cl_event * event, cl_int * errcode_ret); +static cl_int (*pclEnqueueUnmapMemObject)(cl_command_queue command_queue, cl_mem memobj, void * mapped_ptr, + cl_uint num_events_in_wait_list, cl_event * event_wait_list, cl_event * event); +static cl_int (*pclEnqueueNDRangeKernel)(cl_command_queue command_queue, cl_kernel kernel, cl_uint work_dim, + size_t * global_work_offset, size_t * global_work_size, size_t * local_work_size, + cl_uint num_events_in_wait_list, cl_event * event_wait_list, cl_event * event); +static cl_int (*pclEnqueueTask)(cl_command_queue command_queue, cl_kernel kernel, + cl_uint num_events_in_wait_list, cl_event * event_wait_list, cl_event * event); +static cl_int (*pclEnqueueNativeKernel)(cl_command_queue command_queue, + void WINAPI (*user_func)(void *args), + void * args, size_t cb_args, + cl_uint num_mem_objects, const cl_mem * mem_list, const void ** args_mem_loc, + cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event); +static cl_int (*pclEnqueueMarker)(cl_command_queue command_queue, cl_event * event); +static cl_int (*pclEnqueueWaitForEvents)(cl_command_queue command_queue, cl_uint num_events, cl_event * event_list); +static cl_int (*pclEnqueueBarrier)(cl_command_queue command_queue); + +/* Extension function access */ +static void * (*pclGetExtensionFunctionAddress)(const char * func_name); + + +static BOOL init_opencl(void); +static BOOL load_opencl_func(void); + +static void * opencl_handle = NULL; + + +/*********************************************************************** + * DllMain [Internal] + * + * Initializes the internal 'opencl.dll'. + */ +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved) +{ + TRACE("opencl.dll: %p,%x,%p\n", hinstDLL, reason, reserved); + + switch (reason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hinstDLL); + if (init_opencl()) + load_opencl_func(); + break; + + case DLL_PROCESS_DETACH: + if (reserved) break; + if (opencl_handle) wine_dlclose(opencl_handle, NULL, 0); + } + + return TRUE; +} + + +/*********************************************************************** + * init_opencl [Internal] + * + * Initializes OpenCL library. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +static BOOL init_opencl(void) +{ +#ifdef SONAME_LIBOPENCL + char error[256]; + + opencl_handle = wine_dlopen(SONAME_LIBOPENCL, RTLD_NOW, error, sizeof(error)); + if (opencl_handle != NULL) + { + TRACE("Opened library %s\n", SONAME_LIBOPENCL); + return TRUE; + } + else + ERR("Failed to open library %s: %s\n", SONAME_LIBOPENCL, error); +#else + ERR("OpenCL is needed but support was not included at build time\n"); +#endif + return FALSE; +} + + +/*********************************************************************** + * load_opencl_func [Internal] + * + * Populate function table. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +static BOOL load_opencl_func(void) +{ + char error[256]; + + if (opencl_handle == NULL) + return FALSE; + +#define LOAD_FUNCPTR(f) \ + if (!(p##f = wine_dlsym(opencl_handle, #f, error, sizeof(error)))) \ + WARN("%s not found in %s (%s)\n", #f, SONAME_LIBOPENCL, error); + + /* Platform API */ + LOAD_FUNCPTR(clGetPlatformIDs); + LOAD_FUNCPTR(clGetPlatformInfo); + /* Device APIs */ + LOAD_FUNCPTR(clGetDeviceIDs); + LOAD_FUNCPTR(clGetDeviceInfo); + /* Context APIs */ + LOAD_FUNCPTR(clCreateContext); + LOAD_FUNCPTR(clCreateContextFromType); + LOAD_FUNCPTR(clRetainContext); + LOAD_FUNCPTR(clReleaseContext); + LOAD_FUNCPTR(clGetContextInfo); + /* Command Queue APIs */ + LOAD_FUNCPTR(clCreateCommandQueue); + LOAD_FUNCPTR(clRetainCommandQueue); + LOAD_FUNCPTR(clReleaseCommandQueue); + LOAD_FUNCPTR(clGetCommandQueueInfo); + LOAD_FUNCPTR(clSetCommandQueueProperty); + /* Memory Object APIs */ + LOAD_FUNCPTR(clCreateBuffer); + LOAD_FUNCPTR(clCreateImage2D); + LOAD_FUNCPTR(clCreateImage3D); + LOAD_FUNCPTR(clRetainMemObject); + LOAD_FUNCPTR(clReleaseMemObject); + LOAD_FUNCPTR(clGetSupportedImageFormats); + LOAD_FUNCPTR(clGetMemObjectInfo); + LOAD_FUNCPTR(clGetImageInfo); + /* Sampler APIs */ + LOAD_FUNCPTR(clCreateSampler); + LOAD_FUNCPTR(clRetainSampler); + LOAD_FUNCPTR(clReleaseSampler); + LOAD_FUNCPTR(clGetSamplerInfo); + /* Program Object APIs */ + LOAD_FUNCPTR(clCreateProgramWithSource); + LOAD_FUNCPTR(clCreateProgramWithBinary); + LOAD_FUNCPTR(clRetainProgram); + LOAD_FUNCPTR(clReleaseProgram); + LOAD_FUNCPTR(clBuildProgram); + LOAD_FUNCPTR(clUnloadCompiler); + LOAD_FUNCPTR(clGetProgramInfo); + LOAD_FUNCPTR(clGetProgramBuildInfo); + /* Kernel Object APIs */ + LOAD_FUNCPTR(clCreateKernel); + LOAD_FUNCPTR(clCreateKernelsInProgram); + LOAD_FUNCPTR(clRetainKernel); + LOAD_FUNCPTR(clReleaseKernel); + LOAD_FUNCPTR(clSetKernelArg); + LOAD_FUNCPTR(clGetKernelInfo); + LOAD_FUNCPTR(clGetKernelWorkGroupInfo); + /* Event Object APIs */ + LOAD_FUNCPTR(clWaitForEvents); + LOAD_FUNCPTR(clGetEventInfo); + LOAD_FUNCPTR(clRetainEvent); + LOAD_FUNCPTR(clReleaseEvent); + /* Profiling APIs */ + LOAD_FUNCPTR(clGetEventProfilingInfo); + /* Flush and Finish APIs */ + LOAD_FUNCPTR(clFlush); + LOAD_FUNCPTR(clFinish); + /* Enqueued Commands APIs */ + LOAD_FUNCPTR(clEnqueueReadBuffer); + LOAD_FUNCPTR(clEnqueueWriteBuffer); + LOAD_FUNCPTR(clEnqueueCopyBuffer); + LOAD_FUNCPTR(clEnqueueReadImage); + LOAD_FUNCPTR(clEnqueueWriteImage); + LOAD_FUNCPTR(clEnqueueCopyImage); + LOAD_FUNCPTR(clEnqueueCopyImageToBuffer); + LOAD_FUNCPTR(clEnqueueCopyBufferToImage); + LOAD_FUNCPTR(clEnqueueMapBuffer); + LOAD_FUNCPTR(clEnqueueMapImage); + LOAD_FUNCPTR(clEnqueueUnmapMemObject); + LOAD_FUNCPTR(clEnqueueNDRangeKernel); + LOAD_FUNCPTR(clEnqueueTask); + LOAD_FUNCPTR(clEnqueueNativeKernel); + LOAD_FUNCPTR(clEnqueueMarker); + LOAD_FUNCPTR(clEnqueueWaitForEvents); + LOAD_FUNCPTR(clEnqueueBarrier); + /* Extension function access */ + LOAD_FUNCPTR(clGetExtensionFunctionAddress); + +#undef LOAD_FUNCPTR + + return TRUE; +} + + /*---------------------------------------------------------------*/ /* Platform API */
diff --git a/include/config.h.in b/include/config.h.in index 999f4a6130..a08e81c86e 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -1548,6 +1548,9 @@ /* Define to the soname of the libopenal library. */ #undef SONAME_LIBOPENAL
+/* Define to the soname of the libOpenCL library. */ +#undef SONAME_LIBOPENCL + /* Define to the soname of the libOSMesa library. */ #undef SONAME_LIBOSMESA