Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/opencl/make_opencl | 61 ++++++++++++++++ dlls/opencl/opencl_private.h | 3 + dlls/opencl/pe_thunks.c | 47 ++++++++++++ dlls/opencl/pe_wrappers.c | 136 +++++++++++++++++++++++++---------- dlls/opencl/unix_private.h | 11 ++- 5 files changed, 218 insertions(+), 40 deletions(-)
diff --git a/dlls/opencl/make_opencl b/dlls/opencl/make_opencl index f30967ff384..ce9660866ec 100755 --- a/dlls/opencl/make_opencl +++ b/dlls/opencl/make_opencl @@ -52,6 +52,27 @@ my %arg_types = "unsigned int" => [ "long", "%u" ], );
+my %unsupported_extensions = + ( + # Needs wined3d integration. + "cl_intel_d3d11_nv12_media_sharing" => 1, + "cl_intel_dx9_media_sharing" => 1, + "cl_khr_d3d10_sharing" => 1, + "cl_khr_d3d11_sharing" => 1, + "cl_khr_dx9_media_sharing" => 1, + "cl_nv_d3d9_sharing" => 1, + "cl_nv_d3d10_sharing" => 1, + "cl_nv_d3d11_sharing" => 1, + + # Needs a loader/ICD split. + "cl_khr_icd" => 1, + "cl_loader_layers" => 1, + + # Needs callback conversion. + "cl_apple_setmemobjectdestructor" => 1, + "cl_arm_shared_virtual_memory" => 1, + ); + sub generate_pe_thunk($$) { my ($name, $func_ref) = @_; @@ -348,6 +369,16 @@ sub parse_file($) $cl_types{$type->{name}} = $types{$type->{name}}; } } + + # generate extension list + foreach my $ext ($xml->findnodes("/registry/extensions/extension")) + { + # we currently don't support clGetExtensionFunctionAddress, and + # implementing clGetExtensionFunctionAddressForPlatform is nontrivial; + # we need to generate a table of thunks per platform and retrieve the + # platform from the called object + $unsupported_extensions{lc($ext->{name})} = 1 if $ext->findnodes("./require/command"); + } }
parse_file( "cl-$commit.xml" ); @@ -362,6 +393,7 @@ foreach (sort keys %core_functions)
close(SPEC);
+ # generate the PE thunks open(PE, ">$pe_file") or die "cannot create $pe_file";
@@ -379,6 +411,35 @@ foreach (sort keys %core_functions) print PE "\n", generate_pe_thunk( $_, $core_functions{$_} ); }
+print PE <<EOF + +BOOL extension_is_supported( const char *name, size_t len ) +{ + unsigned int i; + + static const char *const unsupported[] = + { +EOF +; + +foreach (sort keys %unsupported_extensions) +{ + print PE " "$_",\n"; +} + +print PE <<EOF + }; + + for (i = 0; i < ARRAY_SIZE(unsupported); ++i) + { + if (!strncasecmp( name, unsupported[i], len )) + return FALSE; + } + return TRUE; +} +EOF +; + close(PE);
# generate the unix library thunks diff --git a/dlls/opencl/opencl_private.h b/dlls/opencl/opencl_private.h index d88f6b2b8b6..78277a42a3b 100644 --- a/dlls/opencl/opencl_private.h +++ b/dlls/opencl/opencl_private.h @@ -21,6 +21,7 @@
#include <stdarg.h> #include <stdint.h> +#include <stdlib.h>
#include "ntstatus.h" #define WIN32_NO_STATUS @@ -30,4 +31,6 @@
#include "wine/debug.h"
+BOOL extension_is_supported( const char *name, size_t len ) DECLSPEC_HIDDEN; + #endif diff --git a/dlls/opencl/pe_thunks.c b/dlls/opencl/pe_thunks.c index eb0466b6286..dc32146fcb4 100644 --- a/dlls/opencl/pe_thunks.c +++ b/dlls/opencl/pe_thunks.c @@ -377,3 +377,50 @@ cl_int WINAPI clWaitForEvents( cl_uint num_events, const cl_event* event_list ) TRACE( "(%u, %p)\n", num_events, event_list ); return opencl_funcs->pclWaitForEvents( num_events, event_list ); } + +BOOL extension_is_supported( const char *name, size_t len ) +{ + unsigned int i; + + static const char *const unsupported[] = + { + "cl_apple_contextloggingfunctions", + "cl_apple_setmemobjectdestructor", + "cl_arm_import_memory", + "cl_arm_shared_virtual_memory", + "cl_ext_device_fission", + "cl_ext_migrate_memobject", + "cl_img_generate_mipmap", + "cl_img_use_gralloc_ptr", + "cl_intel_accelerator", + "cl_intel_create_buffer_with_properties", + "cl_intel_d3d11_nv12_media_sharing", + "cl_intel_dx9_media_sharing", + "cl_intel_unified_shared_memory", + "cl_intel_va_api_media_sharing", + "cl_khr_create_command_queue", + "cl_khr_d3d10_sharing", + "cl_khr_d3d11_sharing", + "cl_khr_dx9_media_sharing", + "cl_khr_egl_event", + "cl_khr_egl_image", + "cl_khr_gl_event", + "cl_khr_gl_sharing", + "cl_khr_icd", + "cl_khr_il_program", + "cl_khr_subgroups", + "cl_khr_terminate_context", + "cl_loader_layers", + "cl_nv_d3d10_sharing", + "cl_nv_d3d11_sharing", + "cl_nv_d3d9_sharing", + "cl_qcom_ext_host_ptr", + }; + + for (i = 0; i < ARRAY_SIZE(unsupported); ++i) + { + if (!strncasecmp( name, unsupported[i], len )) + return FALSE; + } + return TRUE; +} diff --git a/dlls/opencl/pe_wrappers.c b/dlls/opencl/pe_wrappers.c index 77c49064c7b..02e5a962abc 100644 --- a/dlls/opencl/pe_wrappers.c +++ b/dlls/opencl/pe_wrappers.c @@ -26,81 +26,139 @@ WINE_DEFAULT_DEBUG_CHANNEL(opencl);
const struct opencl_funcs *opencl_funcs = NULL;
-cl_int WINAPI clGetPlatformInfo( cl_platform_id platform, cl_platform_info param_name, - SIZE_T param_value_size, void * param_value, size_t * param_value_size_ret ) +static cl_int filter_extensions( const char *unix_exts, SIZE_T size, char *win_exts, size_t *ret_size ) { - cl_int ret; - TRACE("(%p, 0x%x, %ld, %p, %p)\n", platform, param_name, param_value_size, param_value, param_value_size_ret); + char *p = win_exts; + const char *ext; + SIZE_T win_size; + + TRACE( "got host extension string %s\n", debugstr_a( unix_exts ) );
- /* Hide all extensions. - * TODO: Add individual extension support as needed. - */ - if (param_name == CL_PLATFORM_EXTENSIONS) + ext = unix_exts; + win_size = 0; + while (*ext) { - ret = CL_INVALID_VALUE; + const char *end = strchr( ext, ' ' ); + + if (!end) end = ext + strlen( ext ); + + if (extension_is_supported( ext, end - ext )) + win_size += strlen( ext ) + 1;
- if (param_value && param_value_size > 0) + if (*end == ' ') ++end; + ext = end; + } + + if (ret_size) *ret_size = win_size; + if (!win_exts) return CL_SUCCESS; + if (size < win_size) return CL_INVALID_VALUE; + + win_exts[0] = 0; + ext = unix_exts; + while (*ext) + { + const char *end = strchr( ext, ' ' ); + size_t len; + + if (!end) end = ext + strlen( ext ); + len = end - ext; + + if (extension_is_supported( ext, len )) { - char *exts = (char *) param_value; - exts[0] = '\0'; - ret = CL_SUCCESS; + if (p != win_exts) *p++ = ' '; + memcpy( p, ext, len ); + p += len; }
- if (param_value_size_ret) + if (*end == ' ') ++end; + ext = end; + } + *p = 0; + + TRACE( "returning extension string %s\n", debugstr_a(win_exts) ); + + return CL_SUCCESS; +} + +cl_int WINAPI clGetPlatformInfo( cl_platform_id platform, cl_platform_info name, + SIZE_T size, void *value, size_t *ret_size ) +{ + cl_int ret; + + TRACE( "(%p, %#x, %ld, %p, %p)\n", platform, name, size, value, ret_size ); + + if (name == CL_PLATFORM_EXTENSIONS) + { + size_t unix_size; + char *unix_exts; + + ret = opencl_funcs->pclGetPlatformInfo( platform, name, 0, NULL, &unix_size ); + if (ret != CL_SUCCESS) + return ret; + + if (!(unix_exts = malloc( unix_size ))) + return CL_OUT_OF_HOST_MEMORY; + ret = opencl_funcs->pclGetPlatformInfo( platform, name, unix_size, unix_exts, NULL ); + if (ret != CL_SUCCESS) { - *param_value_size_ret = 1; - ret = CL_SUCCESS; + free( unix_exts ); + return ret; } + + ret = filter_extensions( unix_exts, size, value, ret_size ); + + free( unix_exts ); } else { - ret = opencl_funcs->pclGetPlatformInfo(platform, param_name, param_value_size, param_value, param_value_size_ret); + ret = opencl_funcs->pclGetPlatformInfo( platform, name, size, value, ret_size ); }
- TRACE("(%p, 0x%x, %ld, %p, %p)=%d\n", platform, param_name, param_value_size, param_value, param_value_size_ret, ret); return ret; }
-cl_int WINAPI clGetDeviceInfo( cl_device_id device, cl_device_info param_name, - SIZE_T param_value_size, void * param_value, size_t * param_value_size_ret ) +cl_int WINAPI clGetDeviceInfo( cl_device_id device, cl_device_info name, + SIZE_T size, void *value, size_t *ret_size ) { cl_int ret; - TRACE("(%p, 0x%x, %ld, %p, %p)\n",device, param_name, param_value_size, param_value, param_value_size_ret);
- /* Hide all extensions. - * TODO: Add individual extension support as needed. - */ - if (param_name == CL_DEVICE_EXTENSIONS) + TRACE( "(%p, %#x, %ld, %p, %p)\n", device, name, size, value, ret_size ); + + if (name == CL_DEVICE_EXTENSIONS) { - ret = CL_INVALID_VALUE; + size_t unix_size; + char *unix_exts;
- if (param_value && param_value_size > 0) - { - char *exts = (char *) param_value; - exts[0] = '\0'; - ret = CL_SUCCESS; - } + ret = opencl_funcs->pclGetDeviceInfo( device, name, 0, NULL, &unix_size ); + if (ret != CL_SUCCESS) + return ret;
- if (param_value_size_ret) + if (!(unix_exts = malloc( unix_size ))) + return CL_OUT_OF_HOST_MEMORY; + ret = opencl_funcs->pclGetDeviceInfo( device, name, unix_size, unix_exts, NULL ); + if (ret != CL_SUCCESS) { - *param_value_size_ret = 1; - ret = CL_SUCCESS; + free( unix_exts ); + return ret; } + + ret = filter_extensions( unix_exts, size, value, ret_size ); + + free( unix_exts ); } else { - ret = opencl_funcs->pclGetDeviceInfo(device, param_name, param_value_size, param_value, param_value_size_ret); + ret = opencl_funcs->pclGetDeviceInfo( device, name, size, value, ret_size ); }
/* Filter out the CL_EXEC_NATIVE_KERNEL flag */ - if (param_name == CL_DEVICE_EXECUTION_CAPABILITIES) + if (name == CL_DEVICE_EXECUTION_CAPABILITIES) { - cl_device_exec_capabilities *caps = (cl_device_exec_capabilities *) param_value; + cl_device_exec_capabilities *caps = value; *caps &= ~CL_EXEC_NATIVE_KERNEL; }
- TRACE("(%p, 0x%x, %ld, %p, %p)=%d\n",device, param_name, param_value_size, param_value, param_value_size_ret, ret); return ret; }
diff --git a/dlls/opencl/unix_private.h b/dlls/opencl/unix_private.h index 82fb83bd491..d051ade01cc 100644 --- a/dlls/opencl/unix_private.h +++ b/dlls/opencl/unix_private.h @@ -19,7 +19,16 @@ #ifndef __WINE_UNIX_PRIVATE_H #define __WINE_UNIX_PRIVATE_H
-#include "opencl_private.h" +#include <stdarg.h> +#include <stdint.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" + +#include "wine/debug.h"
#define CL_SILENCE_DEPRECATION #if defined(HAVE_CL_CL_H)