Signed-off-by: Nakarin Khankham garuda2550@gmail.com --- dlls/opencl/opencl.c | 188 ++++++++++++++++++++++++++++++++++++++++ dlls/opencl/opencl.spec | 10 +++ 2 files changed, 198 insertions(+)
diff --git a/dlls/opencl/opencl.c b/dlls/opencl/opencl.c index 2d145bf25c..ec046a669e 100644 --- a/dlls/opencl/opencl.c +++ b/dlls/opencl/opencl.c @@ -295,6 +295,21 @@ cl_mem WINAPI wine_clCreateBuffer(cl_context context, cl_mem_flags flags, size_t return ret; }
+cl_mem WINAPI wine_clCreateSubBuffer(cl_mem buffer, cl_mem_flags flags, + cl_buffer_create_type buffer_create_type, const void * buffer_create_info, cl_int * errcode_ret) +{ +#ifdef CL_VERSION_1_1 + cl_mem ret; + TRACE("\n"); + ret = clCreateSubBuffer(buffer, flags, buffer_create_type, buffer_create_info, errcode_ret); + return ret; +#else + FIXME("stub\n"); + *errcode_ret = CL_SUCCESS; + return NULL; +#endif +} + cl_mem WINAPI wine_clCreateImage2D(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) { @@ -357,6 +372,51 @@ cl_int WINAPI wine_clGetImageInfo(cl_mem image, cl_image_info param_name, size_t return ret; }
+#ifdef CL_VERSION_1_1 +typedef struct +{ + void WINAPI (*pfn_notify)(cl_mem memobj, void* user_data); + void *user_data; +} MEM_CALLBACK; + +static void mem_fn_notify(cl_mem memobj, void* user_data) +{ + MEM_CALLBACK *pcb; + FIXME("(%p, %p)\n", memobj, user_data); + pcb = (MEM_CALLBACK *) user_data; + if(pcb->pfn_notify) pcb->pfn_notify(memobj, pcb->user_data); + FIXME("Callback COMPLETED\n"); +} +#endif + +cl_int WINAPI wine_clSetMemObjectDestructorCallback(cl_mem memobj, void WINAPI(*pfn_notify)(cl_mem, void*), void *user_data) +{ +#ifdef CL_VERSION_1_1 + /* FIXME: Based on PROGRAM_CALLBACK/program_fn_notify function. I'm not sure about this. */ + cl_int ret; + FIXME("(%p, %p, %p)\n", memobj, pfn_notify, user_data); + if(pfn_notify) + { + /* When pfn_notify is provided, clSetMemObjectDestructorCallback is asynchronous */ + MEM_CALLBACK *pcb; + pcb = HeapAlloc(GetProcessHeap(), 0, sizeof(MEM_CALLBACK)); + pcb->pfn_notify = pfn_notify; + pcb->user_data = user_data; + ret = clSetMemObjectDestructorCallback(memobj, mem_fn_notify, user_data); + } + else + { + /* When pfn_notify is NULL, clSetMemObjectDestructorCallback is synchronous */ + ret = clSetMemObjectDestructorCallback(memobj, NULL, user_data); + } + FIXME("(%p, %p, %p)=%d\n", memobj, pfn_notify, user_data, ret); + return ret; +#else + FIXME("stub\n"); + return CL_SUCCESS; +#endif +} +
/*---------------------------------------------------------------*/ /* Sampler APIs */ @@ -602,6 +662,79 @@ cl_int WINAPI wine_clReleaseEvent(cl_event event) return ret; }
+cl_event WINAPI wine_clCreateUserEvent(cl_context context, cl_int * errcode_ret) +{ +#ifdef CL_VERSION_1_1 + cl_event ret; + TRACE("\n"); + ret = clCreateUserEvent(context, errcode_ret); + return ret; +#else + FIXME("stub\n"); + *errcode_ret = CL_SUCCESS; + return NULL; +#endif +} + +#ifdef CL_VERSION_1_1 +typedef struct +{ + void WINAPI (*pfn_notify)(cl_event event, cl_int num, void* user_data); + void *user_data; +} EVENT_CALLBACK; + +static void event_fn_notify(cl_event event, cl_int num, void* user_data) +{ + EVENT_CALLBACK *ecb; + FIXME("(%p, %d, %p)\n", event, num, user_data); + ecb = (EVENT_CALLBACK *) user_data; + if(ecb->pfn_notify) ecb->pfn_notify(event, num, ecb->user_data); + FIXME("Callback COMPLETED\n"); +} +#endif + +cl_int WINAPI wine_clSetEventCallback(cl_event event, cl_int command_exec_callback_type, + void WINAPI (*pfn_notify)(cl_event, cl_int, void *), void *user_data) +{ +#ifdef CL_VERSION_1_1 + /* FIXME: Based on PROGRAM_CALLBACK/program_fn_notify function. I'm not sure about this. */ + cl_int ret; + FIXME("(%p, %d, %p, %p)\n", event, command_exec_callback_type, pfn_notify, user_data); + if(pfn_notify) + { + /* When pfn_notify is provided, clSetEventCallback is asynchronous */ + EVENT_CALLBACK *ecb; + ecb = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENT_CALLBACK)); + ecb->pfn_notify = pfn_notify; + ecb->user_data = user_data; + ret = clSetEventCallback(event, command_exec_callback_type, event_fn_notify, user_data); + } + else + { + /* When pfn_notify is NULL, clSetEventCallback is synchronous */ + ret = clSetEventCallback(event, command_exec_callback_type, NULL, user_data); + } + FIXME("(%p, %d, %p, %p)=%d\n", event, command_exec_callback_type, pfn_notify, user_data, ret); + return ret; +#else + FIXME("stub\n"); + return CL_SUCCESS; +#endif +} + +cl_int WINAPI wine_clSetUserEventStatus(cl_event event, cl_int execution_status) +{ +#ifdef CL_VERSION_1_1 + cl_int ret; + TRACE("\n"); + ret = clSetUserEventStatus(event, execution_status); + return ret; +#else + FIXME("stub\n"); + return CL_SUCCESS; +#endif +} +
/*---------------------------------------------------------------*/ /* Profiling APIs */ @@ -651,6 +784,25 @@ cl_int WINAPI wine_clEnqueueReadBuffer(cl_command_queue command_queue, cl_mem bu return ret; }
+cl_int WINAPI wine_clEnqueueReadBufferRect(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, + const size_t * buffer_origin, const size_t * host_origin, const size_t * region, + size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch, + void * ptr, cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event) +{ +#ifdef CL_VERSION_1_1 + cl_int ret; + TRACE("\n"); + ret = clEnqueueReadBufferRect(command_queue, buffer, blocking_read, + buffer_origin, host_origin, region, + buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, + ptr, num_events_in_wait_list, event_wait_list, event); + return ret; +#else + FIXME("stub\n"); + return CL_SUCCESS; +#endif +} + cl_int WINAPI wine_clEnqueueWriteBuffer(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) @@ -661,6 +813,25 @@ cl_int WINAPI wine_clEnqueueWriteBuffer(cl_command_queue command_queue, cl_mem b return ret; }
+cl_int WINAPI wine_clEnqueueWriteBufferRect( cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, + const size_t * buffer_origin, const size_t * host_origin, const size_t * region, + size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch, + const void * ptr, cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event) +{ +#ifdef CL_VERSION_1_1 + cl_int ret; + TRACE("\n"); + ret = clEnqueueWriteBufferRect(command_queue, buffer, blocking_read, + buffer_origin, host_origin, region, + buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, + ptr, num_events_in_wait_list, event_wait_list, event); + return ret; +#else + FIXME("stub\n"); + return CL_SUCCESS; +#endif +} + cl_int WINAPI wine_clEnqueueCopyBuffer(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) @@ -671,6 +842,23 @@ cl_int WINAPI wine_clEnqueueCopyBuffer(cl_command_queue command_queue, cl_mem sr return ret; }
+cl_int WINAPI wine_clEnqueueCopyBufferRect(cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_buffer, + const size_t * src_origin, const size_t * dst_origin, const size_t * region, + size_t src_row_pitch, size_t src_slice_pitch, + size_t dst_row_pitch, size_t dst_slice_pitch, + cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event) +{ +#ifdef CL_VERSION_1_1 + cl_int ret; + TRACE("\n"); + ret = clEnqueueCopyBufferRect(command_queue, src_buffer, dst_buffer, src_origin, dst_origin, region, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch, num_events_in_wait_list, event_wait_list, event); + return ret; +#else + FIXME("stub\n"); + return CL_SUCCESS; +#endif +} + cl_int WINAPI wine_clEnqueueReadImage(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, diff --git a/dlls/opencl/opencl.spec b/dlls/opencl/opencl.spec index ba8ce6e7cd..4782653f3d 100644 --- a/dlls/opencl/opencl.spec +++ b/dlls/opencl/opencl.spec @@ -94,3 +94,13 @@ # @ stdcall clGetGLTextureInfo( long long long ptr ptr ) wine_clGetGLTextureInfo # @ stdcall clEnqueueAcquireGLObjects( long long ptr long ptr ptr ) wine_clEnqueueAcquireGLObjects # @ stdcall clEnqueueReleaseGLObjects( long long ptr long ptr ptr ) wine_clEnqueueReleaseGLObjects + +# OpenCL 1.1 +@ stdcall clCreateSubBuffer( long long long ptr ptr ) wine_clCreateSubBuffer +@ stdcall clCreateUserEvent( long ptr ) wine_clCreateUserEvent +@ stdcall clEnqueueCopyBufferRect( long long long ptr ptr ptr long long long long long ptr ptr ) wine_clEnqueueCopyBufferRect +@ stdcall clEnqueueReadBufferRect( long long long ptr ptr ptr long long long long ptr long ptr ptr ) wine_clEnqueueReadBufferRect +@ stdcall clEnqueueWriteBufferRect( long long long ptr ptr ptr long long long long ptr long ptr ptr ) wine_clEnqueueWriteBufferRect +@ stdcall clSetEventCallback( long long ptr ptr ) wine_clSetEventCallback +@ stdcall clSetMemObjectDestructorCallback( long ptr ptr ) wine_clSetMemObjectDestructorCallback +@ stdcall clSetUserEventStatus( long long ) wine_clSetUserEventStatus
On 3/2/19 2:02 PM, Khral Steelforge wrote:
Signed-off-by: Nakarin Khankham garuda2550@gmail.com
dlls/opencl/opencl.c | 188 ++++++++++++++++++++++++++++++++++++++++ dlls/opencl/opencl.spec | 10 +++ 2 files changed, 198 insertions(+)
diff --git a/dlls/opencl/opencl.c b/dlls/opencl/opencl.c index 2d145bf25c..ec046a669e 100644 --- a/dlls/opencl/opencl.c +++ b/dlls/opencl/opencl.c @@ -295,6 +295,21 @@ cl_mem WINAPI wine_clCreateBuffer(cl_context context, cl_mem_flags flags, size_t return ret; }
+cl_mem WINAPI wine_clCreateSubBuffer(cl_mem buffer, cl_mem_flags flags,
cl_buffer_create_type buffer_create_type, const void * buffer_create_info, cl_int * errcode_ret)
+{ +#ifdef CL_VERSION_1_1
- cl_mem ret;
- TRACE("\n");
- ret = clCreateSubBuffer(buffer, flags, buffer_create_type, buffer_create_info, errcode_ret);
- return ret;
+#else
- FIXME("stub\n");
- *errcode_ret = CL_SUCCESS;
- return NULL;
+#endif +}
Looks like this should be accessed dynamically. How capabilities are reported for OpenCL, e.g. if I've built this with 1.1+ dev library support, and run it on 1.0 host what should happen when application sees 1.1 export?
cl_mem WINAPI wine_clCreateImage2D(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) { @@ -357,6 +372,51 @@ cl_int WINAPI wine_clGetImageInfo(cl_mem image, cl_image_info param_name, size_t return ret; }
+#ifdef CL_VERSION_1_1 +typedef struct +{
- void WINAPI (*pfn_notify)(cl_mem memobj, void* user_data);
- void *user_data;
+} MEM_CALLBACK;
+static void mem_fn_notify(cl_mem memobj, void* user_data) +{
- MEM_CALLBACK *pcb;
- FIXME("(%p, %p)\n", memobj, user_data);
- pcb = (MEM_CALLBACK *) user_data;
- if(pcb->pfn_notify) pcb->pfn_notify(memobj, pcb->user_data);
- FIXME("Callback COMPLETED\n");
+} +#endif
+cl_int WINAPI wine_clSetMemObjectDestructorCallback(cl_mem memobj, void WINAPI(*pfn_notify)(cl_mem, void*), void *user_data) +{ +#ifdef CL_VERSION_1_1
- /* FIXME: Based on PROGRAM_CALLBACK/program_fn_notify function. I'm not sure about this. */
- cl_int ret;
- FIXME("(%p, %p, %p)\n", memobj, pfn_notify, user_data);
- if(pfn_notify)
- {
/* When pfn_notify is provided, clSetMemObjectDestructorCallback is asynchronous */
MEM_CALLBACK *pcb;
pcb = HeapAlloc(GetProcessHeap(), 0, sizeof(MEM_CALLBACK));
pcb->pfn_notify = pfn_notify;
pcb->user_data = user_data;
ret = clSetMemObjectDestructorCallback(memobj, mem_fn_notify, user_data);
- }
- else
- {
/* When pfn_notify is NULL, clSetMemObjectDestructorCallback is synchronous */
ret = clSetMemObjectDestructorCallback(memobj, NULL, user_data);
- }
- FIXME("(%p, %p, %p)=%d\n", memobj, pfn_notify, user_data, ret);
- return ret;
+#else
- FIXME("stub\n");
- return CL_SUCCESS;
+#endif +}
/*---------------------------------------------------------------*/ /* Sampler APIs */
@@ -602,6 +662,79 @@ cl_int WINAPI wine_clReleaseEvent(cl_event event) return ret; }
+cl_event WINAPI wine_clCreateUserEvent(cl_context context, cl_int * errcode_ret) +{ +#ifdef CL_VERSION_1_1
- cl_event ret;
- TRACE("\n");
- ret = clCreateUserEvent(context, errcode_ret);
- return ret;
+#else
- FIXME("stub\n");
- *errcode_ret = CL_SUCCESS;
- return NULL;
+#endif +}
+#ifdef CL_VERSION_1_1 +typedef struct +{
- void WINAPI (*pfn_notify)(cl_event event, cl_int num, void* user_data);
- void *user_data;
+} EVENT_CALLBACK;
+static void event_fn_notify(cl_event event, cl_int num, void* user_data) +{
- EVENT_CALLBACK *ecb;
- FIXME("(%p, %d, %p)\n", event, num, user_data);
- ecb = (EVENT_CALLBACK *) user_data;
- if(ecb->pfn_notify) ecb->pfn_notify(event, num, ecb->user_data);
- FIXME("Callback COMPLETED\n");
+} +#endif
+cl_int WINAPI wine_clSetEventCallback(cl_event event, cl_int command_exec_callback_type,
void WINAPI (*pfn_notify)(cl_event, cl_int, void *), void *user_data)
+{ +#ifdef CL_VERSION_1_1
- /* FIXME: Based on PROGRAM_CALLBACK/program_fn_notify function. I'm not sure about this. */
- cl_int ret;
- FIXME("(%p, %d, %p, %p)\n", event, command_exec_callback_type, pfn_notify, user_data);
- if(pfn_notify)
- {
/* When pfn_notify is provided, clSetEventCallback is asynchronous */
EVENT_CALLBACK *ecb;
ecb = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENT_CALLBACK));
ecb->pfn_notify = pfn_notify;
ecb->user_data = user_data;
ret = clSetEventCallback(event, command_exec_callback_type, event_fn_notify, user_data);
- }
- else
- {
/* When pfn_notify is NULL, clSetEventCallback is synchronous */
ret = clSetEventCallback(event, command_exec_callback_type, NULL, user_data);
- }
- FIXME("(%p, %d, %p, %p)=%d\n", event, command_exec_callback_type, pfn_notify, user_data, ret);
- return ret;
+#else
- FIXME("stub\n");
- return CL_SUCCESS;
+#endif +}
+cl_int WINAPI wine_clSetUserEventStatus(cl_event event, cl_int execution_status) +{ +#ifdef CL_VERSION_1_1
- cl_int ret;
- TRACE("\n");
- ret = clSetUserEventStatus(event, execution_status);
- return ret;
+#else
- FIXME("stub\n");
- return CL_SUCCESS;
+#endif +}
/*---------------------------------------------------------------*/ /* Profiling APIs */
@@ -651,6 +784,25 @@ cl_int WINAPI wine_clEnqueueReadBuffer(cl_command_queue command_queue, cl_mem bu return ret; }
+cl_int WINAPI wine_clEnqueueReadBufferRect(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read,
const size_t * buffer_origin, const size_t * host_origin, const size_t * region,
size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch,
void * ptr, cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event)
+{ +#ifdef CL_VERSION_1_1
- cl_int ret;
- TRACE("\n");
- ret = clEnqueueReadBufferRect(command_queue, buffer, blocking_read,
buffer_origin, host_origin, region,
buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch,
ptr, num_events_in_wait_list, event_wait_list, event);
- return ret;
+#else
- FIXME("stub\n");
- return CL_SUCCESS;
+#endif +}
- cl_int WINAPI wine_clEnqueueWriteBuffer(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)
@@ -661,6 +813,25 @@ cl_int WINAPI wine_clEnqueueWriteBuffer(cl_command_queue command_queue, cl_mem b return ret; }
+cl_int WINAPI wine_clEnqueueWriteBufferRect( cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read,
const size_t * buffer_origin, const size_t * host_origin, const size_t * region,
size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch,
const void * ptr, cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event)
+{ +#ifdef CL_VERSION_1_1
- cl_int ret;
- TRACE("\n");
- ret = clEnqueueWriteBufferRect(command_queue, buffer, blocking_read,
buffer_origin, host_origin, region,
buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch,
ptr, num_events_in_wait_list, event_wait_list, event);
- return ret;
+#else
- FIXME("stub\n");
- return CL_SUCCESS;
+#endif +}
- cl_int WINAPI wine_clEnqueueCopyBuffer(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)
@@ -671,6 +842,23 @@ cl_int WINAPI wine_clEnqueueCopyBuffer(cl_command_queue command_queue, cl_mem sr return ret; }
+cl_int WINAPI wine_clEnqueueCopyBufferRect(cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_buffer,
const size_t * src_origin, const size_t * dst_origin, const size_t * region,
size_t src_row_pitch, size_t src_slice_pitch,
size_t dst_row_pitch, size_t dst_slice_pitch,
cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event)
+{ +#ifdef CL_VERSION_1_1
- cl_int ret;
- TRACE("\n");
- ret = clEnqueueCopyBufferRect(command_queue, src_buffer, dst_buffer, src_origin, dst_origin, region, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch, num_events_in_wait_list, event_wait_list, event);
- return ret;
+#else
- FIXME("stub\n");
- return CL_SUCCESS;
+#endif +}
- cl_int WINAPI wine_clEnqueueReadImage(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,
diff --git a/dlls/opencl/opencl.spec b/dlls/opencl/opencl.spec index ba8ce6e7cd..4782653f3d 100644 --- a/dlls/opencl/opencl.spec +++ b/dlls/opencl/opencl.spec @@ -94,3 +94,13 @@ # @ stdcall clGetGLTextureInfo( long long long ptr ptr ) wine_clGetGLTextureInfo # @ stdcall clEnqueueAcquireGLObjects( long long ptr long ptr ptr ) wine_clEnqueueAcquireGLObjects # @ stdcall clEnqueueReleaseGLObjects( long long ptr long ptr ptr ) wine_clEnqueueReleaseGLObjects
+# OpenCL 1.1 +@ stdcall clCreateSubBuffer( long long long ptr ptr ) wine_clCreateSubBuffer +@ stdcall clCreateUserEvent( long ptr ) wine_clCreateUserEvent +@ stdcall clEnqueueCopyBufferRect( long long long ptr ptr ptr long long long long long ptr ptr ) wine_clEnqueueCopyBufferRect +@ stdcall clEnqueueReadBufferRect( long long long ptr ptr ptr long long long long ptr long ptr ptr ) wine_clEnqueueReadBufferRect +@ stdcall clEnqueueWriteBufferRect( long long long ptr ptr ptr long long long long ptr long ptr ptr ) wine_clEnqueueWriteBufferRect +@ stdcall clSetEventCallback( long long ptr ptr ) wine_clSetEventCallback +@ stdcall clSetMemObjectDestructorCallback( long ptr ptr ) wine_clSetMemObjectDestructorCallback +@ stdcall clSetUserEventStatus( long long ) wine_clSetUserEventStatus
On 02/03/2019 19:18, Nikolay Sivov wrote:
On 3/2/19 2:02 PM, Khral Steelforge wrote:
Signed-off-by: Nakarin Khankham garuda2550@gmail.com
dlls/opencl/opencl.c | 188 ++++++++++++++++++++++++++++++++++++++++ dlls/opencl/opencl.spec | 10 +++ 2 files changed, 198 insertions(+)
diff --git a/dlls/opencl/opencl.c b/dlls/opencl/opencl.c index 2d145bf25c..ec046a669e 100644 --- a/dlls/opencl/opencl.c +++ b/dlls/opencl/opencl.c @@ -295,6 +295,21 @@ cl_mem WINAPI wine_clCreateBuffer(cl_context context, cl_mem_flags flags, size_t return ret; } +cl_mem WINAPI wine_clCreateSubBuffer(cl_mem buffer, cl_mem_flags flags, + cl_buffer_create_type buffer_create_type, const void * buffer_create_info, cl_int * errcode_ret) +{ +#ifdef CL_VERSION_1_1 + cl_mem ret; + TRACE("\n"); + ret = clCreateSubBuffer(buffer, flags, buffer_create_type, buffer_create_info, errcode_ret); + return ret; +#else + FIXME("stub\n"); + *errcode_ret = CL_SUCCESS; + return NULL; +#endif +}
Looks like this should be accessed dynamically. How capabilities are reported for OpenCL, e.g. if I've built this with 1.1+ dev library support, and run it on 1.0 host what should happen when application sees 1.1 export?
Thankyou for the feedback.
By dynamically access the functions, you mean use dlopen and dlsym function? (in wine case, wine_dlopen and wine_dlsym?)
something like this?
... #define SONAME_LIBOPENCL "libOpenCL.so.1" /* this might be better auto generate by the configure script */ static void* opencl_handle = NULL; static cl_mem (*p_clCreateSubBuffer)(cl_mem buffer, cl_mem_flags flags, cl_buffer_create_type buffer_create_type, const void * buffer_create_info, cl_int * errcode_ret); ... cl_mem WINAPI wine_clCreateSubBuffer(cl_mem buffer, cl_mem_flags flags, cl_buffer_create_type buffer_create_type, const void * buffer_create_info, cl_int * errcode_ret) { #ifdef CL_VERSION_1_1 cl_mem ret; char error[200]; TRACE("\n");
if(!opencl_handle) { opencl_handle = wine_dlopen(SONAME_LIBOPENCL, RTLD_NOW, error, sizeof(error)); if (opencl_handle == NULL) { ERR( "Failed to load OpenCL: %s\n", error ); return 0; } }
#define LOAD_FUNCPTR(f) do if (!(p_##f = wine_dlsym( opencl_handle, #f, error, sizeof(error) ))) \ { \ ERR( "%s not found in %s (%s), disabling.\n", #f, SONAME_LIBOPENCL, error ); \ goto failed; \ } while(0)
LOAD_FUNCPTR(clCreateSubBuffer); #undef LOAD_FUNCPTR
ret = p_clCreateSubBuffer(buffer, flags, buffer_create_type, buffer_create_info, errcode_ret); return ret;
failed: wine_dlclose( opencl_handle, NULL, 0 ); opencl_handle = NULL; return 0;
#else FIXME("stub\n"); *errcode_ret = CL_SUCCESS; return NULL; #endif }
If yes, then I think I can improve this patch with guidance from examples in wine's source code.
On Samstag, 2. März 2019 18:57:43 CET Nakarin Khankham wrote:
By dynamically access the functions, you mean use dlopen and dlsym
function?
(in wine case, wine_dlopen and wine_dlsym?)
something like this?
That won't help - once it's compiled with 1.1+ OpenCL support, how is it supposed to react when the host only has OpenCL 1.0 support? You need to check the OpenCL support (of the selected device) dynamically. You can have multiple OpenCL devices with different versions, too.
Regards, Fabian Maurer
On 3/2/19 8:57 PM, Nakarin Khankham wrote:
On 02/03/2019 19:18, Nikolay Sivov wrote:
On 3/2/19 2:02 PM, Khral Steelforge wrote:
Signed-off-by: Nakarin Khankham garuda2550@gmail.com
dlls/opencl/opencl.c | 188 ++++++++++++++++++++++++++++++++++++++++ dlls/opencl/opencl.spec | 10 +++ 2 files changed, 198 insertions(+)
diff --git a/dlls/opencl/opencl.c b/dlls/opencl/opencl.c index 2d145bf25c..ec046a669e 100644 --- a/dlls/opencl/opencl.c +++ b/dlls/opencl/opencl.c @@ -295,6 +295,21 @@ cl_mem WINAPI wine_clCreateBuffer(cl_context context, cl_mem_flags flags, size_t return ret; } +cl_mem WINAPI wine_clCreateSubBuffer(cl_mem buffer, cl_mem_flags flags, + cl_buffer_create_type buffer_create_type, const void * buffer_create_info, cl_int * errcode_ret) +{ +#ifdef CL_VERSION_1_1 + cl_mem ret; + TRACE("\n"); + ret = clCreateSubBuffer(buffer, flags, buffer_create_type, buffer_create_info, errcode_ret); + return ret; +#else + FIXME("stub\n"); + *errcode_ret = CL_SUCCESS; + return NULL; +#endif +}
Looks like this should be accessed dynamically. How capabilities are reported for OpenCL, e.g. if I've built this with 1.1+ dev library support, and run it on 1.0 host what should happen when application sees 1.1 export?
Thankyou for the feedback.
By dynamically access the functions, you mean use dlopen and dlsym function? (in wine case, wine_dlopen and wine_dlsym?)
something like this?
... #define SONAME_LIBOPENCL "libOpenCL.so.1" /* this might be better auto generate by the configure script */ static void* opencl_handle = NULL; static cl_mem (*p_clCreateSubBuffer)(cl_mem buffer, cl_mem_flags flags, cl_buffer_create_type buffer_create_type, const void * buffer_create_info, cl_int * errcode_ret); ... cl_mem WINAPI wine_clCreateSubBuffer(cl_mem buffer, cl_mem_flags flags, cl_buffer_create_type buffer_create_type, const void * buffer_create_info, cl_int * errcode_ret) { #ifdef CL_VERSION_1_1 cl_mem ret; char error[200]; TRACE("\n");
if(!opencl_handle) { opencl_handle = wine_dlopen(SONAME_LIBOPENCL, RTLD_NOW, error, sizeof(error)); if (opencl_handle == NULL) { ERR( "Failed to load OpenCL: %s\n", error ); return 0; } }
#define LOAD_FUNCPTR(f) do if (!(p_##f = wine_dlsym( opencl_handle, #f, error, sizeof(error) ))) \ { \ ERR( "%s not found in %s (%s), disabling.\n", #f, SONAME_LIBOPENCL, error ); \ goto failed; \ } while(0)
LOAD_FUNCPTR(clCreateSubBuffer);
#undef LOAD_FUNCPTR
ret = p_clCreateSubBuffer(buffer, flags, buffer_create_type, buffer_create_info, errcode_ret); return ret;
failed: wine_dlclose( opencl_handle, NULL, 0 ); opencl_handle = NULL; return 0;
#else FIXME("stub\n"); *errcode_ret = CL_SUCCESS; return NULL; #endif }
If yes, then I think I can improve this patch with guidance from examples in wine's source code.
Yes, something like this, except that you can have a single ifdef block to build 1.1 stuff, and then get all function pointers at once, leaving empty exported function bodies in case 1.1 headers where not available at build time.
For example you can look at odbc32/proxyodbc.c.
Ideally, if it's possible, it could be generated from some spec function lists, and then simply iterated over to bind them. See include/wine/wgl_driver.h, and related part in init_opengl() in winex11.drv.
On Sat, Mar 2, 2019 at 10:21 AM Nikolay Sivov nsivov@codeweavers.com wrote:
On 3/2/19 8:57 PM, Nakarin Khankham wrote:
On 02/03/2019 19:18, Nikolay Sivov wrote:
On 3/2/19 2:02 PM, Khral Steelforge wrote:
Signed-off-by: Nakarin Khankham garuda2550@gmail.com
dlls/opencl/opencl.c | 188 ++++++++++++++++++++++++++++++++++++++++ dlls/opencl/opencl.spec | 10 +++ 2 files changed, 198 insertions(+)
diff --git a/dlls/opencl/opencl.c b/dlls/opencl/opencl.c index 2d145bf25c..ec046a669e 100644 --- a/dlls/opencl/opencl.c +++ b/dlls/opencl/opencl.c @@ -295,6 +295,21 @@ cl_mem WINAPI wine_clCreateBuffer(cl_context context, cl_mem_flags flags, size_t return ret; } +cl_mem WINAPI wine_clCreateSubBuffer(cl_mem buffer, cl_mem_flags flags,
cl_buffer_create_type buffer_create_type, const void * buffer_create_info, cl_int * errcode_ret)
+{ +#ifdef CL_VERSION_1_1
- cl_mem ret;
- TRACE("\n");
- ret = clCreateSubBuffer(buffer, flags, buffer_create_type, buffer_create_info, errcode_ret);
- return ret;
+#else
- FIXME("stub\n");
- *errcode_ret = CL_SUCCESS;
- return NULL;
+#endif +}
Looks like this should be accessed dynamically. How capabilities are reported for OpenCL, e.g. if I've built this with 1.1+ dev library support, and run it on 1.0 host what should happen when application sees 1.1 export?
Thankyou for the feedback.
By dynamically access the functions, you mean use dlopen and dlsym function? (in wine case, wine_dlopen and wine_dlsym?)
something like this?
... #define SONAME_LIBOPENCL "libOpenCL.so.1" /* this might be better auto generate by the configure script */ static void* opencl_handle = NULL; static cl_mem (*p_clCreateSubBuffer)(cl_mem buffer, cl_mem_flags flags, cl_buffer_create_type buffer_create_type, const void * buffer_create_info, cl_int * errcode_ret); ... cl_mem WINAPI wine_clCreateSubBuffer(cl_mem buffer, cl_mem_flags flags, cl_buffer_create_type buffer_create_type, const void * buffer_create_info, cl_int * errcode_ret) { #ifdef CL_VERSION_1_1 cl_mem ret; char error[200]; TRACE("\n");
if(!opencl_handle) { opencl_handle = wine_dlopen(SONAME_LIBOPENCL, RTLD_NOW, error, sizeof(error)); if (opencl_handle == NULL) { ERR( "Failed to load OpenCL: %s\n", error ); return 0; } }
#define LOAD_FUNCPTR(f) do if (!(p_##f = wine_dlsym( opencl_handle, #f, error, sizeof(error) ))) \ { \ ERR( "%s not found in %s (%s), disabling.\n", #f, SONAME_LIBOPENCL, error ); \ goto failed; \ } while(0)
LOAD_FUNCPTR(clCreateSubBuffer);
#undef LOAD_FUNCPTR
ret = p_clCreateSubBuffer(buffer, flags, buffer_create_type, buffer_create_info, errcode_ret); return ret;
failed: wine_dlclose( opencl_handle, NULL, 0 ); opencl_handle = NULL; return 0;
#else FIXME("stub\n"); *errcode_ret = CL_SUCCESS; return NULL; #endif }
If yes, then I think I can improve this patch with guidance from examples in wine's source code.
Yes, something like this, except that you can have a single ifdef block to build 1.1 stuff, and then get all function pointers at once, leaving empty exported function bodies in case 1.1 headers where not available at build time.
For example you can look at odbc32/proxyodbc.c.
Ideally, if it's possible, it could be generated from some spec function lists, and then simply iterated over to bind them. See include/wine/wgl_driver.h, and related part in init_opengl() in winex11.drv.
Continuing a bit on this note. Currently whatever scripts have been used to generate opencl, are not in Wine, which is bad and makes updating hard (e.g. adding new extensions etcetera). It should be part of Wine.
The other issue is that if I'm truly honest the architecture of our opencl DLL is not correct (not sure if looking back it should have been merged the way it was). So far the opencl library focused on just the opencl bits, but opencl allows for interop with OpenGL, Direct3D and Vulkan. Just a simple passthrough like now is not sufficient for that I think. Not sure how we should do it though. We could follow the ICD standard for it,.. not sure what it would buy though, but we may have to go that way for interop.
On 03/03/2019 01:20, Nikolay Sivov wrote:
Yes, something like this, except that you can have a single ifdef block to build 1.1 stuff, and then get all function pointers at once, leaving empty exported function bodies in case 1.1 headers where not available at build time.
For example you can look at odbc32/proxyodbc.c.
Ideally, if it's possible, it could be generated from some spec function lists, and then simply iterated over to bind them. See include/wine/wgl_driver.h, and related part in init_opengl() in winex11.drv.
Thanks, I'll look into and use it as example.