1 #![allow(non_snake_case)]
2
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::platform::*;
10 use crate::api::program::*;
11 use crate::api::queue::*;
12 use crate::api::types::*;
13 use crate::api::util::*;
14
15 use mesa_rust_util::ptr::*;
16 use rusticl_opencl_gen::*;
17
18 use std::ffi::c_char;
19 use std::ffi::c_void;
20 use std::ffi::CStr;
21 use std::ptr;
22 use std::sync::Arc;
23
24 pub static DISPATCH: cl_icd_dispatch = cl_icd_dispatch {
25 clGetPlatformIDs: Some(clGetPlatformIDs),
26 clGetPlatformInfo: Some(clGetPlatformInfo),
27 clGetDeviceIDs: Some(clGetDeviceIDs),
28 clGetDeviceInfo: Some(clGetDeviceInfo),
29 clCreateContext: Some(clCreateContext),
30 clCreateContextFromType: Some(clCreateContextFromType),
31 clRetainContext: Some(clRetainContext),
32 clReleaseContext: Some(clReleaseContext),
33 clGetContextInfo: Some(clGetContextInfo),
34 clCreateCommandQueue: Some(clCreateCommandQueue),
35 clRetainCommandQueue: Some(clRetainCommandQueue),
36 clReleaseCommandQueue: Some(clReleaseCommandQueue),
37 clGetCommandQueueInfo: Some(clGetCommandQueueInfo),
38 clSetCommandQueueProperty: Some(clSetCommandQueueProperty),
39 clCreateBuffer: Some(clCreateBuffer),
40 clCreateImage2D: Some(clCreateImage2D),
41 clCreateImage3D: Some(clCreateImage3D),
42 clRetainMemObject: Some(clRetainMemObject),
43 clReleaseMemObject: Some(clReleaseMemObject),
44 clGetSupportedImageFormats: Some(clGetSupportedImageFormats),
45 clGetMemObjectInfo: Some(clGetMemObjectInfo),
46 clGetImageInfo: Some(clGetImageInfo),
47 clCreateSampler: Some(clCreateSampler),
48 clRetainSampler: Some(clRetainSampler),
49 clReleaseSampler: Some(clReleaseSampler),
50 clGetSamplerInfo: Some(clGetSamplerInfo),
51 clCreateProgramWithSource: Some(clCreateProgramWithSource),
52 clCreateProgramWithBinary: Some(clCreateProgramWithBinary),
53 clRetainProgram: Some(clRetainProgram),
54 clReleaseProgram: Some(clReleaseProgram),
55 clBuildProgram: Some(clBuildProgram),
56 clUnloadCompiler: None,
57 clGetProgramInfo: Some(clGetProgramInfo),
58 clGetProgramBuildInfo: Some(clGetProgramBuildInfo),
59 clCreateKernel: Some(clCreateKernel),
60 clCreateKernelsInProgram: Some(clCreateKernelsInProgram),
61 clRetainKernel: Some(clRetainKernel),
62 clReleaseKernel: Some(clReleaseKernel),
63 clSetKernelArg: Some(clSetKernelArg),
64 clGetKernelInfo: Some(clGetKernelInfo),
65 clGetKernelWorkGroupInfo: Some(clGetKernelWorkGroupInfo),
66 clWaitForEvents: Some(clWaitForEvents),
67 clGetEventInfo: Some(clGetEventInfo),
68 clRetainEvent: Some(clRetainEvent),
69 clReleaseEvent: Some(clReleaseEvent),
70 clGetEventProfilingInfo: Some(clGetEventProfilingInfo),
71 clFlush: Some(clFlush),
72 clFinish: Some(clFinish),
73 clEnqueueReadBuffer: Some(clEnqueueReadBuffer),
74 clEnqueueWriteBuffer: Some(clEnqueueWriteBuffer),
75 clEnqueueCopyBuffer: Some(clEnqueueCopyBuffer),
76 clEnqueueReadImage: Some(clEnqueueReadImage),
77 clEnqueueWriteImage: Some(clEnqueueWriteImage),
78 clEnqueueCopyImage: Some(clEnqueueCopyImage),
79 clEnqueueCopyImageToBuffer: Some(clEnqueueCopyImageToBuffer),
80 clEnqueueCopyBufferToImage: Some(clEnqueueCopyBufferToImage),
81 clEnqueueMapBuffer: Some(clEnqueueMapBuffer),
82 clEnqueueMapImage: Some(clEnqueueMapImage),
83 clEnqueueUnmapMemObject: Some(clEnqueueUnmapMemObject),
84 clEnqueueNDRangeKernel: Some(clEnqueueNDRangeKernel),
85 clEnqueueTask: Some(clEnqueueTask),
86 clEnqueueNativeKernel: None,
87 clEnqueueMarker: Some(clEnqueueMarker),
88 clEnqueueWaitForEvents: None,
89 clEnqueueBarrier: Some(clEnqueueBarrier),
90 clGetExtensionFunctionAddress: Some(clGetExtensionFunctionAddress),
91 clCreateFromGLBuffer: Some(clCreateFromGLBuffer),
92 clCreateFromGLTexture2D: Some(clCreateFromGLTexture2D),
93 clCreateFromGLTexture3D: Some(clCreateFromGLTexture3D),
94 clCreateFromGLRenderbuffer: Some(clCreateFromGLRenderbuffer),
95 clGetGLObjectInfo: Some(clGetGLObjectInfo),
96 clGetGLTextureInfo: Some(clGetGLTextureInfo),
97 clEnqueueAcquireGLObjects: Some(clEnqueueAcquireGLObjects),
98 clEnqueueReleaseGLObjects: Some(clEnqueueReleaseGLObjects),
99 clGetGLContextInfoKHR: Some(clGetGLContextInfoKHR),
100 clGetDeviceIDsFromD3D10KHR: ptr::null_mut(),
101 clCreateFromD3D10BufferKHR: ptr::null_mut(),
102 clCreateFromD3D10Texture2DKHR: ptr::null_mut(),
103 clCreateFromD3D10Texture3DKHR: ptr::null_mut(),
104 clEnqueueAcquireD3D10ObjectsKHR: ptr::null_mut(),
105 clEnqueueReleaseD3D10ObjectsKHR: ptr::null_mut(),
106 clSetEventCallback: Some(clSetEventCallback),
107 clCreateSubBuffer: Some(clCreateSubBuffer),
108 clSetMemObjectDestructorCallback: Some(clSetMemObjectDestructorCallback),
109 clCreateUserEvent: Some(clCreateUserEvent),
110 clSetUserEventStatus: Some(clSetUserEventStatus),
111 clEnqueueReadBufferRect: Some(clEnqueueReadBufferRect),
112 clEnqueueWriteBufferRect: Some(clEnqueueWriteBufferRect),
113 clEnqueueCopyBufferRect: Some(clEnqueueCopyBufferRect),
114 clCreateSubDevicesEXT: None,
115 clRetainDeviceEXT: None,
116 clReleaseDeviceEXT: None,
117 clCreateEventFromGLsyncKHR: None,
118 clCreateSubDevices: Some(clCreateSubDevices),
119 clRetainDevice: Some(clRetainDevice),
120 clReleaseDevice: Some(clReleaseDevice),
121 clCreateImage: Some(clCreateImage),
122 clCreateProgramWithBuiltInKernels: None,
123 clCompileProgram: Some(clCompileProgram),
124 clLinkProgram: Some(clLinkProgram),
125 clUnloadPlatformCompiler: Some(clUnloadPlatformCompiler),
126 clGetKernelArgInfo: Some(clGetKernelArgInfo),
127 clEnqueueFillBuffer: Some(clEnqueueFillBuffer),
128 clEnqueueFillImage: Some(clEnqueueFillImage),
129 clEnqueueMigrateMemObjects: Some(clEnqueueMigrateMemObjects),
130 clEnqueueMarkerWithWaitList: Some(clEnqueueMarkerWithWaitList),
131 clEnqueueBarrierWithWaitList: Some(clEnqueueBarrierWithWaitList),
132 clGetExtensionFunctionAddressForPlatform: Some(clGetExtensionFunctionAddressForPlatform),
133 clCreateFromGLTexture: Some(clCreateFromGLTexture),
134 clGetDeviceIDsFromD3D11KHR: ptr::null_mut(),
135 clCreateFromD3D11BufferKHR: ptr::null_mut(),
136 clCreateFromD3D11Texture2DKHR: ptr::null_mut(),
137 clCreateFromD3D11Texture3DKHR: ptr::null_mut(),
138 clCreateFromDX9MediaSurfaceKHR: ptr::null_mut(),
139 clEnqueueAcquireD3D11ObjectsKHR: ptr::null_mut(),
140 clEnqueueReleaseD3D11ObjectsKHR: ptr::null_mut(),
141 clGetDeviceIDsFromDX9MediaAdapterKHR: ptr::null_mut(),
142 clEnqueueAcquireDX9MediaSurfacesKHR: ptr::null_mut(),
143 clEnqueueReleaseDX9MediaSurfacesKHR: ptr::null_mut(),
144 clCreateFromEGLImageKHR: None,
145 clEnqueueAcquireEGLObjectsKHR: None,
146 clEnqueueReleaseEGLObjectsKHR: None,
147 clCreateEventFromEGLSyncKHR: None,
148 clCreateCommandQueueWithProperties: Some(clCreateCommandQueueWithProperties),
149 clCreatePipe: Some(clCreatePipe),
150 clGetPipeInfo: Some(clGetPipeInfo),
151 clSVMAlloc: Some(clSVMAlloc),
152 clSVMFree: Some(clSVMFree),
153 clEnqueueSVMFree: Some(clEnqueueSVMFree),
154 clEnqueueSVMMemcpy: Some(clEnqueueSVMMemcpy),
155 clEnqueueSVMMemFill: Some(clEnqueueSVMMemFill),
156 clEnqueueSVMMap: Some(clEnqueueSVMMap),
157 clEnqueueSVMUnmap: Some(clEnqueueSVMUnmap),
158 clCreateSamplerWithProperties: Some(clCreateSamplerWithProperties),
159 clSetKernelArgSVMPointer: Some(clSetKernelArgSVMPointer),
160 clSetKernelExecInfo: Some(clSetKernelExecInfo),
161 clGetKernelSubGroupInfoKHR: Some(clGetKernelSubGroupInfo),
162 clCloneKernel: Some(clCloneKernel),
163 clCreateProgramWithIL: Some(clCreateProgramWithIL),
164 clEnqueueSVMMigrateMem: Some(clEnqueueSVMMigrateMem),
165 clGetDeviceAndHostTimer: Some(clGetDeviceAndHostTimer),
166 clGetHostTimer: Some(clGetHostTimer),
167 clGetKernelSubGroupInfo: Some(clGetKernelSubGroupInfo),
168 clSetDefaultDeviceCommandQueue: Some(clSetDefaultDeviceCommandQueue),
169 clSetProgramReleaseCallback: Some(clSetProgramReleaseCallback),
170 clSetProgramSpecializationConstant: Some(clSetProgramSpecializationConstant),
171 clCreateBufferWithProperties: Some(clCreateBufferWithProperties),
172 clCreateImageWithProperties: Some(clCreateImageWithProperties),
173 clSetContextDestructorCallback: Some(clSetContextDestructorCallback),
174 };
175
176 pub type CLError = cl_int;
177 pub type CLResult<T> = Result<T, CLError>;
178
179 #[derive(Clone, Copy, PartialEq)]
180 #[repr(u32)]
181 pub enum RusticlTypes {
182 // random number
183 Buffer = 0xec4cf9a9,
184 Context,
185 Device,
186 Event,
187 Image,
188 Kernel,
189 Program,
190 Queue,
191 Sampler,
192 }
193
194 impl RusticlTypes {
u32(&self) -> u32195 pub const fn u32(&self) -> u32 {
196 *self as u32
197 }
198
from_u32(val: u32) -> Option<Self>199 pub const fn from_u32(val: u32) -> Option<Self> {
200 let result = match val {
201 0xec4cf9a9 => Self::Buffer,
202 0xec4cf9aa => Self::Context,
203 0xec4cf9ab => Self::Device,
204 0xec4cf9ac => Self::Event,
205 0xec4cf9ad => Self::Image,
206 0xec4cf9ae => Self::Kernel,
207 0xec4cf9af => Self::Program,
208 0xec4cf9b0 => Self::Queue,
209 0xec4cf9b1 => Self::Sampler,
210 _ => return None,
211 };
212 debug_assert!(result.u32() == val);
213 Some(result)
214 }
215 }
216
217 #[repr(C)]
218 pub struct CLObjectBase<const ERR: i32> {
219 dispatch: &'static cl_icd_dispatch,
220 rusticl_type: u32,
221 }
222
223 impl<const ERR: i32> CLObjectBase<ERR> {
new(t: RusticlTypes) -> Self224 pub fn new(t: RusticlTypes) -> Self {
225 Self {
226 dispatch: &DISPATCH,
227 rusticl_type: t.u32(),
228 }
229 }
230
check_ptr(ptr: *const Self) -> CLResult<RusticlTypes>231 pub fn check_ptr(ptr: *const Self) -> CLResult<RusticlTypes> {
232 if ptr.is_null() {
233 return Err(ERR);
234 }
235
236 unsafe {
237 if !::std::ptr::eq((*ptr).dispatch, &DISPATCH) {
238 return Err(ERR);
239 }
240
241 let Some(ty) = RusticlTypes::from_u32((*ptr).rusticl_type) else {
242 return Err(ERR);
243 };
244
245 Ok(ty)
246 }
247 }
248
get_type(&self) -> CLResult<RusticlTypes>249 pub fn get_type(&self) -> CLResult<RusticlTypes> {
250 RusticlTypes::from_u32(self.rusticl_type).ok_or(ERR)
251 }
252 }
253
254 pub trait ReferenceCountedAPIPointer<T, const ERR: i32> {
get_ptr(&self) -> CLResult<*const T>255 fn get_ptr(&self) -> CLResult<*const T>;
256
257 // TODO: I can't find a trait that would let me say T: pointer so that
258 // I can do the cast in the main trait implementation. So we need to
259 // implement that as part of the macro where we know the real type.
from_ptr(ptr: *const T) -> Self260 fn from_ptr(ptr: *const T) -> Self;
261 }
262
263 pub trait BaseCLObject<'a, const ERR: i32, CL: ReferenceCountedAPIPointer<Self, ERR> + 'a>:
264 Sized
265 {
ref_from_raw(obj: CL) -> CLResult<&'a Self>266 fn ref_from_raw(obj: CL) -> CLResult<&'a Self> {
267 let obj = obj.get_ptr()?;
268 // SAFETY: `get_ptr` already checks if it's one of our pointers and not null
269 Ok(unsafe { &*obj })
270 }
271
refs_from_arr(objs: *const CL, count: u32) -> CLResult<Vec<&'a Self>> where CL: Copy,272 fn refs_from_arr(objs: *const CL, count: u32) -> CLResult<Vec<&'a Self>>
273 where
274 CL: Copy,
275 {
276 // CL spec requires validation for obj arrays, both values have to make sense
277 if objs.is_null() && count > 0 || !objs.is_null() && count == 0 {
278 return Err(CL_INVALID_VALUE);
279 }
280
281 let mut res = Vec::new();
282 if objs.is_null() || count == 0 {
283 return Ok(res);
284 }
285
286 for i in 0..count as usize {
287 res.push(Self::ref_from_raw(unsafe { *objs.add(i) })?);
288 }
289 Ok(res)
290 }
291 }
292
293 pub trait ArcedCLObject<'a, const ERR: i32, CL: ReferenceCountedAPIPointer<Self, ERR> + 'a>:
294 Sized + BaseCLObject<'a, ERR, CL>
295 {
296 /// Note: this operation increases the internal ref count as `ref_from_raw` is the better option
297 /// when an Arc is not needed.
arc_from_raw(ptr: CL) -> CLResult<Arc<Self>>298 fn arc_from_raw(ptr: CL) -> CLResult<Arc<Self>> {
299 let ptr = ptr.get_ptr()?;
300 // SAFETY: `get_ptr` already checks if it's one of our pointers.
301 Ok(unsafe {
302 Arc::increment_strong_count(ptr);
303 Arc::from_raw(ptr)
304 })
305 }
306
arcs_from_arr(objs: *const CL, count: u32) -> CLResult<Vec<Arc<Self>>> where CL: Copy,307 fn arcs_from_arr(objs: *const CL, count: u32) -> CLResult<Vec<Arc<Self>>>
308 where
309 CL: Copy,
310 {
311 // CL spec requires validation for obj arrays, both values have to make sense
312 if objs.is_null() && count > 0 || !objs.is_null() && count == 0 {
313 return Err(CL_INVALID_VALUE);
314 }
315
316 let mut res = Vec::new();
317 if objs.is_null() || count == 0 {
318 return Ok(res);
319 }
320
321 for i in 0..count as usize {
322 unsafe {
323 res.push(Self::arc_from_raw(*objs.add(i))?);
324 }
325 }
326 Ok(res)
327 }
328
refcnt(ptr: CL) -> CLResult<u32>329 fn refcnt(ptr: CL) -> CLResult<u32> {
330 let ptr = ptr.get_ptr()?;
331 // SAFETY: `get_ptr` already checks if it's one of our pointers.
332 let arc = unsafe { Arc::from_raw(ptr) };
333 let res = Arc::strong_count(&arc);
334 // leak the arc again, so we don't reduce the refcount by dropping `arc`
335 let _ = Arc::into_raw(arc);
336 Ok(res as u32)
337 }
338
into_cl(self: Arc<Self>) -> CL339 fn into_cl(self: Arc<Self>) -> CL {
340 CL::from_ptr(Arc::into_raw(self))
341 }
342
release(ptr: CL) -> CLResult<()>343 fn release(ptr: CL) -> CLResult<()> {
344 let ptr = ptr.get_ptr()?;
345 // SAFETY: `get_ptr` already checks if it's one of our pointers.
346 unsafe { Arc::decrement_strong_count(ptr) };
347 Ok(())
348 }
349
retain(ptr: CL) -> CLResult<()>350 fn retain(ptr: CL) -> CLResult<()> {
351 let ptr = ptr.get_ptr()?;
352 // SAFETY: `get_ptr` already checks if it's one of our pointers.
353 unsafe { Arc::increment_strong_count(ptr) };
354 Ok(())
355 }
356 }
357
358 #[macro_export]
359 macro_rules! impl_cl_type_trait_base {
360 (@BASE $cl: ident, $t: ident, [$($types: ident),+], $err: ident, $($field:ident).+) => {
361 impl $crate::api::icd::ReferenceCountedAPIPointer<$t, $err> for $cl {
362 fn get_ptr(&self) -> CLResult<*const $t> {
363 type Base = $crate::api::icd::CLObjectBase<$err>;
364 let t = Base::check_ptr(self.cast())?;
365 if ![$($crate::api::icd::RusticlTypes::$types),+].contains(&t) {
366 return Err($err);
367 }
368
369 let offset = ::mesa_rust_util::offset_of!($t, $($field).+);
370 // SAFETY: We offset the pointer back from the ICD specified base type to our
371 // internal type.
372 let obj_ptr: *const $t = unsafe { self.byte_sub(offset) }.cast();
373
374 // Check at compile-time that we indeed got the right path
375 unsafe { let _: &Base = &(*obj_ptr).$($field).+; }
376
377 Ok(obj_ptr)
378 }
379
380 fn from_ptr(ptr: *const $t) -> Self {
381 if ptr.is_null() {
382 return std::ptr::null_mut();
383 }
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
386 // base type.
387 unsafe { ptr.byte_add(offset) as Self }
388 }
389 }
390
391 impl $crate::api::icd::BaseCLObject<'_, $err, $cl> for $t {}
392
393 impl $t {
394 fn _ensure_send_sync(&self) -> impl Send + Sync + '_ {
395 self
396 }
397 }
398
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 std::ptr::addr_eq(self, other)
407 }
408 }
409
410 impl std::hash::Hash for $t {
411 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
412 std::ptr::from_ref(self).hash(state);
413 }
414 }
415 };
416
417 ($cl: ident, $t: ident, [$($types: ident),+], $err: ident, $($field:ident).+) => {
418 $crate::impl_cl_type_trait_base!(@BASE $cl, $t, [$($types),+], $err, $($field).+);
419 };
420
421 ($cl: ident, $t: ident, [$($types: ident),+], $err: ident) => {
422 $crate::impl_cl_type_trait_base!($cl, $t, [$($types),+], $err, base);
423 };
424 }
425
426 #[macro_export]
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 {}
431 };
432
433 ($cl: ident, $t: ident, $err: ident) => {
434 $crate::impl_cl_type_trait!($cl, $t, $err, base);
435 };
436 }
437
438 // We need those functions exported
439
440 #[no_mangle]
clGetPlatformInfo( platform: cl_platform_id, param_name: cl_platform_info, param_value_size: usize, param_value: *mut ::std::ffi::c_void, param_value_size_ret: *mut usize, ) -> cl_int441 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,
447 ) -> cl_int {
448 platform::clGetPlatformInfo(
449 platform,
450 param_name,
451 param_value_size,
452 param_value,
453 param_value_size_ret,
454 )
455 }
456
457 #[no_mangle]
clIcdGetPlatformIDsKHR( num_entries: cl_uint, platforms: *mut cl_platform_id, num_platforms: *mut cl_uint, ) -> cl_int458 extern "C" fn clIcdGetPlatformIDsKHR(
459 num_entries: cl_uint,
460 platforms: *mut cl_platform_id,
461 num_platforms: *mut cl_uint,
462 ) -> cl_int {
463 clGetPlatformIDs(num_entries, platforms, num_platforms)
464 }
465
466 macro_rules! cl_ext_func {
467 ($func:ident: $api_type:ident) => {{
468 let _func: $api_type = Some($func);
469 $func as *mut ::std::ffi::c_void
470 }};
471 }
472
473 #[rustfmt::skip]
474 #[no_mangle]
clGetExtensionFunctionAddress( function_name: *const c_char, ) -> *mut c_void475 extern "C" fn clGetExtensionFunctionAddress(
476 function_name: *const c_char,
477 ) -> *mut c_void {
478 if function_name.is_null() {
479 return ptr::null_mut();
480 }
481 match unsafe { CStr::from_ptr(function_name) }.to_str().unwrap() {
482 // cl_khr_create_command_queue
483 "clCreateCommandQueueWithPropertiesKHR" => cl_ext_func!(clCreateCommandQueueWithProperties: clCreateCommandQueueWithPropertiesKHR_fn),
484
485 // cl_khr_icd
486 "clGetPlatformInfo" => cl_ext_func!(clGetPlatformInfo: cl_api_clGetPlatformInfo),
487 "clIcdGetPlatformIDsKHR" => cl_ext_func!(clIcdGetPlatformIDsKHR: clIcdGetPlatformIDsKHR_fn),
488
489 // cl_khr_il_program
490 "clCreateProgramWithILKHR" => cl_ext_func!(clCreateProgramWithIL: clCreateProgramWithILKHR_fn),
491
492 // cl_khr_gl_sharing
493 "clCreateFromGLBuffer" => cl_ext_func!(clCreateFromGLBuffer: cl_api_clCreateFromGLBuffer),
494 "clCreateFromGLRenderbuffer" => cl_ext_func!(clCreateFromGLRenderbuffer: cl_api_clCreateFromGLRenderbuffer),
495 "clCreateFromGLTexture" => cl_ext_func!(clCreateFromGLTexture: cl_api_clCreateFromGLTexture),
496 "clCreateFromGLTexture2D" => cl_ext_func!(clCreateFromGLTexture2D: cl_api_clCreateFromGLTexture2D),
497 "clCreateFromGLTexture3D" => cl_ext_func!(clCreateFromGLTexture3D: cl_api_clCreateFromGLTexture3D),
498 "clEnqueueAcquireGLObjects" => cl_ext_func!(clEnqueueAcquireGLObjects: cl_api_clEnqueueAcquireGLObjects),
499 "clEnqueueReleaseGLObjects" => cl_ext_func!(clEnqueueReleaseGLObjects: cl_api_clEnqueueReleaseGLObjects),
500 "clGetGLContextInfoKHR" => cl_ext_func!(clGetGLContextInfoKHR: cl_api_clGetGLContextInfoKHR),
501 "clGetGLObjectInfo" => cl_ext_func!(clGetGLObjectInfo: cl_api_clGetGLObjectInfo),
502 "clGetGLTextureInfo" => cl_ext_func!(clGetGLTextureInfo: cl_api_clGetGLTextureInfo),
503
504 // cl_khr_suggested_local_work_size
505 "clGetKernelSuggestedLocalWorkSizeKHR" => cl_ext_func!(clGetKernelSuggestedLocalWorkSizeKHR: clGetKernelSuggestedLocalWorkSizeKHR_fn),
506
507 // cl_arm_shared_virtual_memory
508 "clEnqueueSVMFreeARM" => cl_ext_func!(clEnqueueSVMFreeARM: cl_api_clEnqueueSVMFree),
509 "clEnqueueSVMMapARM" => cl_ext_func!(clEnqueueSVMMapARM: cl_api_clEnqueueSVMMap),
510 "clEnqueueSVMMemcpyARM" => cl_ext_func!(clEnqueueSVMMemcpyARM: cl_api_clEnqueueSVMMemcpy),
511 "clEnqueueSVMMemFillARM" => cl_ext_func!(clEnqueueSVMMemFillARM: cl_api_clEnqueueSVMMemFill),
512 "clEnqueueSVMUnmapARM" => cl_ext_func!(clEnqueueSVMUnmapARM: cl_api_clEnqueueSVMUnmap),
513 "clSetKernelArgSVMPointerARM" => cl_ext_func!(clSetKernelArgSVMPointer: cl_api_clSetKernelArgSVMPointer),
514 "clSetKernelExecInfoARM" => cl_ext_func!(clSetKernelExecInfo: cl_api_clSetKernelExecInfo),
515 "clSVMAllocARM" => cl_ext_func!(clSVMAlloc: cl_api_clSVMAlloc),
516 "clSVMFreeARM" => cl_ext_func!(clSVMFree: cl_api_clSVMFree),
517
518 // DPCPP bug https://github.com/intel/llvm/issues/9964
519 "clSetProgramSpecializationConstant" => cl_ext_func!(clSetProgramSpecializationConstant: cl_api_clSetProgramSpecializationConstant),
520
521 _ => ptr::null_mut(),
522 }
523 }
524
clLinkProgram( context: cl_context, num_devices: cl_uint, device_list: *const cl_device_id, options: *const ::std::os::raw::c_char, num_input_programs: cl_uint, input_programs: *const cl_program, pfn_notify: Option<FuncProgramCB>, user_data: *mut ::std::os::raw::c_void, errcode_ret: *mut cl_int, ) -> cl_program525 extern "C" fn clLinkProgram(
526 context: cl_context,
527 num_devices: cl_uint,
528 device_list: *const cl_device_id,
529 options: *const ::std::os::raw::c_char,
530 num_input_programs: cl_uint,
531 input_programs: *const cl_program,
532 pfn_notify: Option<FuncProgramCB>,
533 user_data: *mut ::std::os::raw::c_void,
534 errcode_ret: *mut cl_int,
535 ) -> cl_program {
536 let (ptr, err) = match link_program(
537 context,
538 num_devices,
539 device_list,
540 options,
541 num_input_programs,
542 input_programs,
543 pfn_notify,
544 user_data,
545 ) {
546 Ok((prog, code)) => (prog, code),
547 Err(e) => (ptr::null_mut(), e),
548 };
549
550 errcode_ret.write_checked(err);
551 ptr
552 }
553
clGetExtensionFunctionAddressForPlatform( _platform: cl_platform_id, function_name: *const ::std::os::raw::c_char, ) -> *mut ::std::os::raw::c_void554 extern "C" fn clGetExtensionFunctionAddressForPlatform(
555 _platform: cl_platform_id,
556 function_name: *const ::std::os::raw::c_char,
557 ) -> *mut ::std::os::raw::c_void {
558 clGetExtensionFunctionAddress(function_name)
559 }
560
clSVMAlloc( context: cl_context, flags: cl_svm_mem_flags, size: usize, alignment: ::std::os::raw::c_uint, ) -> *mut ::std::os::raw::c_void561 extern "C" fn clSVMAlloc(
562 context: cl_context,
563 flags: cl_svm_mem_flags,
564 size: usize,
565 alignment: ::std::os::raw::c_uint,
566 ) -> *mut ::std::os::raw::c_void {
567 svm_alloc(context, flags, size, alignment).unwrap_or(ptr::null_mut())
568 }
569
clSVMFree(context: cl_context, svm_pointer: *mut ::std::os::raw::c_void)570 extern "C" fn clSVMFree(context: cl_context, svm_pointer: *mut ::std::os::raw::c_void) {
571 svm_free(context, svm_pointer as usize).ok();
572 }
573
clGetKernelSubGroupInfo( kernel: cl_kernel, device: cl_device_id, param_name: cl_kernel_sub_group_info, input_value_size: usize, input_value: *const ::std::os::raw::c_void, param_value_size: usize, param_value: *mut ::std::os::raw::c_void, param_value_size_ret: *mut usize, ) -> cl_int574 extern "C" fn clGetKernelSubGroupInfo(
575 kernel: cl_kernel,
576 device: cl_device_id,
577 param_name: cl_kernel_sub_group_info,
578 input_value_size: usize,
579 input_value: *const ::std::os::raw::c_void,
580 param_value_size: usize,
581 param_value: *mut ::std::os::raw::c_void,
582 param_value_size_ret: *mut usize,
583 ) -> cl_int {
584 match kernel.get_info_obj(
585 (device, input_value_size, input_value, param_value_size),
586 param_name,
587 param_value_size,
588 param_value,
589 param_value_size_ret,
590 ) {
591 Ok(_) => CL_SUCCESS as cl_int,
592 Err(e) => e,
593 }
594 }
595