1 #![allow(non_snake_case)]
3 use crate::api::context::*;
4 use crate::api::device::*;
5 use crate::api::event::*;
6 use crate::api::kernel::*;
7 use crate::api::memory::*;
8 use crate::api::platform::*;
9 use crate::api::program::*;
10 use crate::api::queue::*;
11 use crate::api::types::*;
12 use crate::api::util::*;
14 use mesa_rust_util::ptr::*;
15 use rusticl_opencl_gen::*;
21 pub static DISPATCH: cl_icd_dispatch = cl_icd_dispatch {
22 clGetPlatformIDs: Some(cl_get_platform_ids),
23 clGetPlatformInfo: Some(cl_get_platform_info),
24 clGetDeviceIDs: Some(cl_get_device_ids),
25 clGetDeviceInfo: Some(cl_get_device_info),
26 clCreateContext: Some(cl_create_context),
27 clCreateContextFromType: Some(cl_create_context_from_type),
28 clRetainContext: Some(cl_retain_context),
29 clReleaseContext: Some(cl_release_context),
30 clGetContextInfo: Some(cl_get_context_info),
31 clCreateCommandQueue: Some(cl_create_command_queue),
32 clRetainCommandQueue: Some(cl_retain_command_queue),
33 clReleaseCommandQueue: Some(cl_release_command_queue),
34 clGetCommandQueueInfo: Some(cl_get_command_queue_info),
35 clSetCommandQueueProperty: None,
36 clCreateBuffer: Some(cl_create_buffer),
37 clCreateImage2D: Some(cl_create_image_2d),
38 clCreateImage3D: Some(cl_create_image_3d),
39 clRetainMemObject: Some(cl_retain_mem_object),
40 clReleaseMemObject: Some(cl_release_mem_object),
41 clGetSupportedImageFormats: Some(cl_get_supported_image_formats),
42 clGetMemObjectInfo: Some(cl_get_mem_object_info),
43 clGetImageInfo: Some(cl_get_image_info),
44 clCreateSampler: Some(cl_create_sampler),
45 clRetainSampler: Some(cl_retain_sampler),
46 clReleaseSampler: Some(cl_release_sampler),
47 clGetSamplerInfo: Some(cl_get_sampler_info),
48 clCreateProgramWithSource: Some(cl_create_program_with_source),
49 clCreateProgramWithBinary: Some(cl_create_program_with_binary),
50 clRetainProgram: Some(cl_retain_program),
51 clReleaseProgram: Some(cl_release_program),
52 clBuildProgram: Some(cl_build_program),
53 clUnloadCompiler: None,
54 clGetProgramInfo: Some(cl_get_program_info),
55 clGetProgramBuildInfo: Some(cl_get_program_build_info),
56 clCreateKernel: Some(cl_create_kernel),
57 clCreateKernelsInProgram: Some(cl_create_kernels_in_program),
58 clRetainKernel: Some(cl_retain_kernel),
59 clReleaseKernel: Some(cl_release_kernel),
60 clSetKernelArg: Some(cl_set_kernel_arg),
61 clGetKernelInfo: Some(cl_get_kernel_info),
62 clGetKernelWorkGroupInfo: Some(cl_get_kernel_work_group_info),
63 clWaitForEvents: Some(cl_wait_for_events),
64 clGetEventInfo: Some(cl_get_event_info),
65 clRetainEvent: Some(cl_retain_event),
66 clReleaseEvent: Some(cl_release_event),
67 clGetEventProfilingInfo: Some(cl_get_event_profiling_info),
68 clFlush: Some(cl_flush),
69 clFinish: Some(cl_finish),
70 clEnqueueReadBuffer: Some(cl_enqueue_read_buffer),
71 clEnqueueWriteBuffer: Some(cl_enqueue_write_buffer),
72 clEnqueueCopyBuffer: Some(cl_enqueue_copy_buffer),
73 clEnqueueReadImage: Some(cl_enqueue_read_image),
74 clEnqueueWriteImage: Some(cl_enqueue_write_image),
75 clEnqueueCopyImage: Some(cl_enqueue_copy_image),
76 clEnqueueCopyImageToBuffer: Some(cl_enqueue_copy_image_to_buffer),
77 clEnqueueCopyBufferToImage: Some(cl_enqueue_copy_buffer_to_image),
78 clEnqueueMapBuffer: Some(cl_enqueue_map_buffer),
79 clEnqueueMapImage: Some(cl_enqueue_map_image),
80 clEnqueueUnmapMemObject: Some(cl_enqueue_unmap_mem_object),
81 clEnqueueNDRangeKernel: Some(cl_enqueue_ndrange_kernel),
82 clEnqueueTask: Some(cl_enqueue_task),
83 clEnqueueNativeKernel: None,
84 clEnqueueMarker: Some(cl_enqueue_marker),
85 clEnqueueWaitForEvents: None,
86 clEnqueueBarrier: Some(cl_enqueue_barrier),
87 clGetExtensionFunctionAddress: Some(cl_get_extension_function_address),
88 clCreateFromGLBuffer: Some(cl_create_from_gl_buffer),
89 clCreateFromGLTexture2D: Some(cl_create_from_gl_texture_2d),
90 clCreateFromGLTexture3D: Some(cl_create_from_gl_texture_3d),
91 clCreateFromGLRenderbuffer: Some(cl_create_from_gl_renderbuffer),
92 clGetGLObjectInfo: Some(cl_get_gl_object_info),
93 clGetGLTextureInfo: Some(cl_get_gl_texture_info),
94 clEnqueueAcquireGLObjects: Some(cl_enqueue_acquire_gl_objects),
95 clEnqueueReleaseGLObjects: Some(cl_enqueue_release_gl_objects),
96 clGetGLContextInfoKHR: Some(cl_get_gl_context_info_khr),
97 clGetDeviceIDsFromD3D10KHR: ptr::null_mut(),
98 clCreateFromD3D10BufferKHR: ptr::null_mut(),
99 clCreateFromD3D10Texture2DKHR: ptr::null_mut(),
100 clCreateFromD3D10Texture3DKHR: ptr::null_mut(),
101 clEnqueueAcquireD3D10ObjectsKHR: ptr::null_mut(),
102 clEnqueueReleaseD3D10ObjectsKHR: ptr::null_mut(),
103 clSetEventCallback: Some(cl_set_event_callback),
104 clCreateSubBuffer: Some(cl_create_sub_buffer),
105 clSetMemObjectDestructorCallback: Some(cl_set_mem_object_destructor_callback),
106 clCreateUserEvent: Some(cl_create_user_event),
107 clSetUserEventStatus: Some(cl_set_user_event_status),
108 clEnqueueReadBufferRect: Some(cl_enqueue_read_buffer_rect),
109 clEnqueueWriteBufferRect: Some(cl_enqueue_write_buffer_rect),
110 clEnqueueCopyBufferRect: Some(cl_enqueue_copy_buffer_rect),
111 clCreateSubDevicesEXT: None,
112 clRetainDeviceEXT: None,
113 clReleaseDeviceEXT: None,
114 clCreateEventFromGLsyncKHR: None,
115 clCreateSubDevices: None,
116 clRetainDevice: Some(cl_retain_device),
117 clReleaseDevice: Some(cl_release_device),
118 clCreateImage: Some(cl_create_image),
119 clCreateProgramWithBuiltInKernels: None,
120 clCompileProgram: Some(cl_compile_program),
121 clLinkProgram: Some(cl_link_program),
122 clUnloadPlatformCompiler: Some(cl_unload_platform_compiler),
123 clGetKernelArgInfo: Some(cl_get_kernel_arg_info),
124 clEnqueueFillBuffer: Some(cl_enqueue_fill_buffer),
125 clEnqueueFillImage: Some(cl_enqueue_fill_image),
126 clEnqueueMigrateMemObjects: Some(cl_enqueue_migrate_mem_objects),
127 clEnqueueMarkerWithWaitList: Some(cl_enqueue_marker_with_wait_list),
128 clEnqueueBarrierWithWaitList: Some(cl_enqueue_barrier_with_wait_list),
129 clGetExtensionFunctionAddressForPlatform: Some(cl_get_extension_function_address_for_platform),
130 clCreateFromGLTexture: Some(cl_create_from_gl_texture),
131 clGetDeviceIDsFromD3D11KHR: ptr::null_mut(),
132 clCreateFromD3D11BufferKHR: ptr::null_mut(),
133 clCreateFromD3D11Texture2DKHR: ptr::null_mut(),
134 clCreateFromD3D11Texture3DKHR: ptr::null_mut(),
135 clCreateFromDX9MediaSurfaceKHR: ptr::null_mut(),
136 clEnqueueAcquireD3D11ObjectsKHR: ptr::null_mut(),
137 clEnqueueReleaseD3D11ObjectsKHR: ptr::null_mut(),
138 clGetDeviceIDsFromDX9MediaAdapterKHR: ptr::null_mut(),
139 clEnqueueAcquireDX9MediaSurfacesKHR: ptr::null_mut(),
140 clEnqueueReleaseDX9MediaSurfacesKHR: ptr::null_mut(),
141 clCreateFromEGLImageKHR: None,
142 clEnqueueAcquireEGLObjectsKHR: None,
143 clEnqueueReleaseEGLObjectsKHR: None,
144 clCreateEventFromEGLSyncKHR: None,
145 clCreateCommandQueueWithProperties: Some(cl_create_command_queue_with_properties),
146 clCreatePipe: Some(cl_create_pipe),
147 clGetPipeInfo: Some(cl_get_pipe_info),
148 clSVMAlloc: Some(cl_svm_alloc),
149 clSVMFree: Some(cl_svm_free),
150 clEnqueueSVMFree: Some(cl_enqueue_svm_free),
151 clEnqueueSVMMemcpy: Some(cl_enqueue_svm_memcpy),
152 clEnqueueSVMMemFill: Some(cl_enqueue_svm_mem_fill),
153 clEnqueueSVMMap: Some(cl_enqueue_svm_map),
154 clEnqueueSVMUnmap: Some(cl_enqueue_svm_unmap),
155 clCreateSamplerWithProperties: Some(cl_create_sampler_with_properties),
156 clSetKernelArgSVMPointer: Some(cl_set_kernel_arg_svm_pointer),
157 clSetKernelExecInfo: Some(cl_set_kernel_exec_info),
158 clGetKernelSubGroupInfoKHR: Some(cl_get_kernel_sub_group_info),
159 clCloneKernel: Some(cl_clone_kernel),
160 clCreateProgramWithIL: Some(cl_create_program_with_il),
161 clEnqueueSVMMigrateMem: Some(cl_enqueue_svm_migrate_mem),
162 clGetDeviceAndHostTimer: Some(cl_get_device_and_host_timer),
163 clGetHostTimer: Some(cl_get_host_timer),
164 clGetKernelSubGroupInfo: Some(cl_get_kernel_sub_group_info),
165 clSetDefaultDeviceCommandQueue: Some(cl_set_default_device_command_queue),
166 clSetProgramReleaseCallback: Some(cl_set_program_release_callback),
167 clSetProgramSpecializationConstant: Some(cl_set_program_specialization_constant),
168 clCreateBufferWithProperties: Some(cl_create_buffer_with_properties),
169 clCreateImageWithProperties: Some(cl_create_image_with_properties),
170 clSetContextDestructorCallback: Some(cl_set_context_destructor_callback),
173 pub type CLError = cl_int;
174 pub type CLResult<T> = Result<T, CLError>;
176 #[derive(Clone, Copy, PartialEq)]
178 pub enum RusticlTypes {
192 pub const fn u32(&self) -> u32 {
196 pub const fn from_u32(val: u32) -> Option<Self> {
197 let result = match val {
198 0xec4cf9a9 => Self::Buffer,
199 0xec4cf9aa => Self::Context,
200 0xec4cf9ab => Self::Device,
201 0xec4cf9ac => Self::Event,
202 0xec4cf9ad => Self::Image,
203 0xec4cf9ae => Self::Kernel,
204 0xec4cf9af => Self::Program,
205 0xec4cf9b0 => Self::Queue,
206 0xec4cf9b1 => Self::Sampler,
209 debug_assert!(result.u32() == val);
215 pub struct CLObjectBase<const ERR: i32> {
216 dispatch: &'static cl_icd_dispatch,
220 impl<const ERR: i32> CLObjectBase<ERR> {
221 pub fn new(t: RusticlTypes) -> Self {
224 rusticl_type: t.u32(),
228 pub fn check_ptr(ptr: *const Self) -> CLResult<RusticlTypes> {
234 if !::std::ptr::eq((*ptr).dispatch, &DISPATCH) {
238 let Some(ty) = RusticlTypes::from_u32((*ptr).rusticl_type) else {
246 pub fn get_type(&self) -> CLResult<RusticlTypes> {
247 RusticlTypes::from_u32(self.rusticl_type).ok_or(ERR)
251 pub trait ReferenceCountedAPIPointer<T, const ERR: i32> {
252 fn get_ptr(&self) -> CLResult<*const T>;
254 // TODO: I can't find a trait that would let me say T: pointer so that
255 // I can do the cast in the main trait implementation. So we need to
256 // implement that as part of the macro where we know the real type.
257 fn from_ptr(ptr: *const T) -> Self;
260 pub trait BaseCLObject<'a, const ERR: i32, CL: ReferenceCountedAPIPointer<Self, ERR> + 'a>:
263 fn ref_from_raw(obj: CL) -> CLResult<&'a Self> {
264 let obj = obj.get_ptr()?;
265 // SAFETY: `get_ptr` already checks if it's one of our pointers and not null
269 fn refs_from_arr(objs: *const CL, count: u32) -> CLResult<Vec<&'a Self>>
273 // CL spec requires validation for obj arrays, both values have to make sense
274 if objs.is_null() && count > 0 || !objs.is_null() && count == 0 {
275 return Err(CL_INVALID_VALUE);
278 let mut res = Vec::new();
279 if objs.is_null() || count == 0 {
283 for i in 0..count as usize {
284 res.push(Self::ref_from_raw(unsafe { *objs.add(i) })?);
290 pub trait ArcedCLObject<'a, const ERR: i32, CL: ReferenceCountedAPIPointer<Self, ERR> + 'a>:
291 Sized + BaseCLObject<'a, ERR, CL>
293 /// Note: this operation increases the internal ref count as `ref_from_raw` is the better option
294 /// when an Arc is not needed.
295 fn arc_from_raw(ptr: CL) -> CLResult<Arc<Self>> {
296 let ptr = ptr.get_ptr()?;
297 // SAFETY: `get_ptr` already checks if it's one of our pointers.
299 Arc::increment_strong_count(ptr);
304 fn arcs_from_arr(objs: *const CL, count: u32) -> CLResult<Vec<Arc<Self>>>
308 // CL spec requires validation for obj arrays, both values have to make sense
309 if objs.is_null() && count > 0 || !objs.is_null() && count == 0 {
310 return Err(CL_INVALID_VALUE);
313 let mut res = Vec::new();
314 if objs.is_null() || count == 0 {
318 for i in 0..count as usize {
320 res.push(Self::arc_from_raw(*objs.add(i))?);
326 fn refcnt(ptr: CL) -> CLResult<u32> {
327 let ptr = ptr.get_ptr()?;
328 // SAFETY: `get_ptr` already checks if it's one of our pointers.
329 let arc = unsafe { Arc::from_raw(ptr) };
330 let res = Arc::strong_count(&arc);
331 // leak the arc again, so we don't reduce the refcount by dropping `arc`
332 let _ = Arc::into_raw(arc);
336 fn into_cl(self: Arc<Self>) -> CL {
337 CL::from_ptr(Arc::into_raw(self))
340 fn release(ptr: CL) -> CLResult<()> {
341 let ptr = ptr.get_ptr()?;
342 // SAFETY: `get_ptr` already checks if it's one of our pointers.
343 unsafe { Arc::decrement_strong_count(ptr) };
347 fn retain(ptr: CL) -> CLResult<()> {
348 let ptr = ptr.get_ptr()?;
349 // SAFETY: `get_ptr` already checks if it's one of our pointers.
350 unsafe { Arc::increment_strong_count(ptr) };
356 macro_rules! impl_cl_type_trait_base {
357 (@BASE $cl: ident, $t: ident, [$($types: ident),+], $err: ident, $($field:ident).+) => {
358 impl $crate::api::icd::ReferenceCountedAPIPointer<$t, $err> for $cl {
359 fn get_ptr(&self) -> CLResult<*const $t> {
360 type Base = $crate::api::icd::CLObjectBase<$err>;
361 let t = Base::check_ptr(self.cast())?;
362 if ![$($crate::api::icd::RusticlTypes::$types),+].contains(&t) {
366 let offset = ::mesa_rust_util::offset_of!($t, $($field).+);
367 let mut obj_ptr: *const u8 = self.cast();
368 // SAFETY: We offset the pointer back from the ICD specified base type to our
370 unsafe { obj_ptr = obj_ptr.sub(offset) }
372 let obj_ptr: *const $t = obj_ptr.cast();
374 // Check at compile-time that we indeed got the right path
375 unsafe { let _: &Base = &(*obj_ptr).$($field).+; }
380 fn from_ptr(ptr: *const $t) -> Self {
382 return std::ptr::null_mut();
384 let offset = ::mesa_rust_util::offset_of!($t, $($field).+);
385 // SAFETY: The resulting pointer is safe as we simply offset into the ICD specified
387 unsafe { (ptr as *const u8).add(offset) as Self }
391 impl $crate::api::icd::BaseCLObject<'_, $err, $cl> for $t {}
394 fn _ensure_send_sync(&self) -> impl Send + Sync + '_ {
399 // there are two reason to implement those traits for all objects
400 // 1. it speeds up operations
401 // 2. we want to check for real equality more explicit to stay conformant with the API
402 // and to not break in subtle ways e.g. using CL objects as keys in HashMaps.
403 impl std::cmp::Eq for $t {}
404 impl std::cmp::PartialEq for $t {
405 fn eq(&self, other: &Self) -> bool {
406 (self as *const Self) == (other as *const Self)
410 impl std::hash::Hash for $t {
411 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
412 (self as *const Self).hash(state);
417 ($cl: ident, $t: ident, [$($types: ident),+], $err: ident, $($field:ident).+) => {
418 $crate::impl_cl_type_trait_base!(@BASE $cl, $t, [$($types),+], $err, $($field).+);
421 ($cl: ident, $t: ident, [$($types: ident),+], $err: ident) => {
422 $crate::impl_cl_type_trait_base!($cl, $t, [$($types),+], $err, base);
427 macro_rules! impl_cl_type_trait {
428 ($cl: ident, $t: ident, $err: ident, $($field:ident).+) => {
429 $crate::impl_cl_type_trait_base!(@BASE $cl, $t, [$t], $err, $($field).+);
430 impl $crate::api::icd::ArcedCLObject<'_, $err, $cl> for $t {}
433 ($cl: ident, $t: ident, $err: ident) => {
434 $crate::impl_cl_type_trait!($cl, $t, $err, base);
438 // We need those functions exported
441 extern "C" fn clGetPlatformInfo(
442 platform: cl_platform_id,
443 param_name: cl_platform_info,
444 param_value_size: usize,
445 param_value: *mut ::std::ffi::c_void,
446 param_value_size_ret: *mut usize,
448 cl_get_platform_info(
453 param_value_size_ret,
458 extern "C" fn clGetExtensionFunctionAddress(
459 function_name: *const ::std::os::raw::c_char,
460 ) -> *mut ::std::ffi::c_void {
461 cl_get_extension_function_address(function_name)
465 extern "C" fn clIcdGetPlatformIDsKHR(
466 num_entries: cl_uint,
467 platforms: *mut cl_platform_id,
468 num_platforms: *mut cl_uint,
470 cl_get_platform_ids(num_entries, platforms, num_platforms)
473 extern "C" fn cl_get_extension_function_address(
474 function_name: *const ::std::os::raw::c_char,
475 ) -> *mut ::std::ffi::c_void {
476 if function_name.is_null() {
477 return ptr::null_mut();
479 match unsafe { CStr::from_ptr(function_name) }.to_str().unwrap() {
480 // cl_khr_create_command_queue
481 "clCreateCommandQueueWithPropertiesKHR" => {
482 cl_create_command_queue_with_properties as *mut ::std::ffi::c_void
486 "clGetPlatformInfo" => cl_get_platform_info as *mut ::std::ffi::c_void,
487 "clIcdGetPlatformIDsKHR" => cl_get_platform_ids as *mut ::std::ffi::c_void,
490 "clCreateProgramWithILKHR" => cl_create_program_with_il as *mut ::std::ffi::c_void,
493 "clCreateFromGLBuffer" => cl_create_from_gl_buffer as *mut ::std::ffi::c_void,
494 "clCreateFromGLRenderbuffer" => cl_create_from_gl_renderbuffer as *mut ::std::ffi::c_void,
495 "clCreateFromGLTexture" => cl_create_from_gl_texture as *mut ::std::ffi::c_void,
496 "clCreateFromGLTexture2D" => cl_create_from_gl_texture_2d as *mut ::std::ffi::c_void,
497 "clCreateFromGLTexture3D" => cl_create_from_gl_texture_3d as *mut ::std::ffi::c_void,
498 "clEnqueueAcquireGLObjects" => cl_enqueue_acquire_gl_objects as *mut ::std::ffi::c_void,
499 "clEnqueueReleaseGLObjects" => cl_enqueue_release_gl_objects as *mut ::std::ffi::c_void,
500 "clGetGLContextInfoKHR" => cl_get_gl_context_info_khr as *mut ::std::ffi::c_void,
501 "clGetGLObjectInfo" => cl_get_gl_object_info as *mut ::std::ffi::c_void,
502 "clGetGLTextureInfo" => cl_get_gl_texture_info as *mut ::std::ffi::c_void,
504 // cl_khr_suggested_local_work_size
505 "clGetKernelSuggestedLocalWorkSizeKHR" => {
506 cl_get_kernel_suggested_local_work_size_khr as *mut ::std::ffi::c_void
509 // cl_arm_shared_virtual_memory
510 "clEnqueueSVMFreeARM" => cl_enqueue_svm_free_arm as *mut ::std::ffi::c_void,
511 "clEnqueueSVMMapARM" => cl_enqueue_svm_map_arm as *mut ::std::ffi::c_void,
512 "clEnqueueSVMMemcpyARM" => cl_enqueue_svm_memcpy_arm as *mut ::std::ffi::c_void,
513 "clEnqueueSVMMemFillARM" => cl_enqueue_svm_mem_fill_arm as *mut ::std::ffi::c_void,
514 "clEnqueueSVMUnmapARM" => cl_enqueue_svm_unmap_arm as *mut ::std::ffi::c_void,
515 "clSetKernelArgSVMPointerARM" => cl_set_kernel_arg_svm_pointer as *mut ::std::ffi::c_void,
516 "clSetKernelExecInfoARM" => cl_set_kernel_exec_info as *mut ::std::ffi::c_void,
517 "clSVMAllocARM" => cl_svm_alloc as *mut ::std::ffi::c_void,
518 "clSVMFreeARM" => cl_svm_free as *mut ::std::ffi::c_void,
520 // DPCPP bug https://github.com/intel/llvm/issues/9964
521 "clSetProgramSpecializationConstant" => {
522 cl_set_program_specialization_constant as *mut ::std::ffi::c_void
525 _ => ptr::null_mut(),
529 extern "C" fn cl_link_program(
531 num_devices: cl_uint,
532 device_list: *const cl_device_id,
533 options: *const ::std::os::raw::c_char,
534 num_input_programs: cl_uint,
535 input_programs: *const cl_program,
536 pfn_notify: Option<FuncProgramCB>,
537 user_data: *mut ::std::os::raw::c_void,
538 errcode_ret: *mut cl_int,
540 let (ptr, err) = match link_program(
550 Ok((prog, code)) => (prog, code),
551 Err(e) => (ptr::null_mut(), e),
554 errcode_ret.write_checked(err);
558 extern "C" fn cl_get_extension_function_address_for_platform(
559 _platform: cl_platform_id,
560 function_name: *const ::std::os::raw::c_char,
561 ) -> *mut ::std::os::raw::c_void {
562 cl_get_extension_function_address(function_name)
565 extern "C" fn cl_svm_alloc(
567 flags: cl_svm_mem_flags,
569 alignment: ::std::os::raw::c_uint,
570 ) -> *mut ::std::os::raw::c_void {
571 svm_alloc(context, flags, size, alignment).unwrap_or(ptr::null_mut())
574 extern "C" fn cl_svm_free(context: cl_context, svm_pointer: *mut ::std::os::raw::c_void) {
575 svm_free(context, svm_pointer as usize).ok();
578 extern "C" fn cl_get_kernel_sub_group_info(
580 device: cl_device_id,
581 param_name: cl_kernel_sub_group_info,
582 input_value_size: usize,
583 input_value: *const ::std::os::raw::c_void,
584 param_value_size: usize,
585 param_value: *mut ::std::os::raw::c_void,
586 param_value_size_ret: *mut usize,
588 match kernel.get_info_obj(
589 (device, input_value_size, input_value, param_value_size),
593 param_value_size_ret,
595 Ok(_) => CL_SUCCESS as cl_int,