[PATCH v2 2/4] opencl: Expose extensions that don't use new commands.

Zebediah Figura z.figura12 at gmail.com
Sat Mar 20 15:59:23 CDT 2021


Signed-off-by: Zebediah Figura <z.figura12 at 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)
-- 
2.31.0




More information about the wine-devel mailing list