cl3/
ext.rs

1// Copyright (c) 2021-2025 Via Technology Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! `OpenCL` extensions that don't have external (OpenGL, D3D) dependencies.
16//! See: [OpenCL Extension Specification](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_Ext.html)
17
18#![allow(unused_unsafe)]
19#![allow(non_camel_case_types)]
20#![allow(
21    clippy::not_unsafe_ptr_arg_deref,
22    clippy::wildcard_in_or_patterns,
23    clippy::missing_safety_doc,
24    clippy::too_many_arguments
25)]
26
27pub use opencl_sys::*;
28
29#[allow(unused_imports)]
30use super::error_codes::DLOPEN_FUNCTION_NOT_AVAILABLE;
31#[allow(unused_imports)]
32use super::info_type::InfoType;
33#[allow(unused_imports)]
34use super::{api_info_size, api_info_value, api_info_vector};
35#[allow(unused_imports)]
36use libc::{c_char, c_int, c_void, intptr_t, size_t};
37#[allow(unused_imports)]
38use std::mem;
39#[allow(unused_imports)]
40use std::ptr;
41
42#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
43#[allow(clippy::cast_possible_truncation)]
44pub fn create_command_buffer_khr(
45    queues: &[cl_command_queue],
46    properties: *const cl_command_buffer_properties_khr,
47) -> Result<cl_command_buffer_khr, cl_int> {
48    let mut status: cl_int = CL_INVALID_VALUE;
49    let buffer = unsafe {
50        cl_call!(clCreateCommandBufferKHR(
51            queues.len() as cl_uint,
52            queues.as_ptr(),
53            properties,
54            &raw mut status,
55        ))
56    };
57    if CL_SUCCESS == status {
58        Ok(buffer)
59    } else {
60        Err(status)
61    }
62}
63
64#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
65pub fn finalize_command_buffer_khr(command_buffer: cl_command_buffer_khr) -> Result<(), cl_int> {
66    let status: cl_int = unsafe { cl_call!(clFinalizeCommandBufferKHR(command_buffer)) };
67    if CL_SUCCESS == status {
68        Ok(())
69    } else {
70        Err(status)
71    }
72}
73
74#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
75pub unsafe fn retain_command_buffer_khr(
76    command_buffer: cl_command_buffer_khr,
77) -> Result<(), cl_int> {
78    let status: cl_int = cl_call!(clRetainCommandBufferKHR(command_buffer));
79    if CL_SUCCESS == status {
80        Ok(())
81    } else {
82        Err(status)
83    }
84}
85
86#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
87pub unsafe fn release_command_buffer_khr(
88    command_buffer: cl_command_buffer_khr,
89) -> Result<(), cl_int> {
90    let status: cl_int = cl_call!(clReleaseCommandBufferKHR(command_buffer));
91    if CL_SUCCESS == status {
92        Ok(())
93    } else {
94        Err(status)
95    }
96}
97
98#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
99pub unsafe fn enqueue_command_buffer_khr(
100    num_queues: cl_uint,
101    queues: *mut cl_command_queue,
102    command_buffer: cl_command_buffer_khr,
103    num_events_in_wait_list: cl_uint,
104    event_wait_list: *const cl_event,
105) -> Result<cl_event, cl_int> {
106    let mut event: cl_event = ptr::null_mut();
107    let status: cl_int = cl_call!(clEnqueueCommandBufferKHR(
108        num_queues,
109        queues,
110        command_buffer,
111        num_events_in_wait_list,
112        event_wait_list,
113        &raw mut event,
114    ));
115    if CL_SUCCESS == status {
116        Ok(event)
117    } else {
118        Err(status)
119    }
120}
121
122#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
123#[allow(clippy::cast_possible_truncation)]
124pub unsafe fn command_barrier_with_wait_list_khr(
125    command_buffer: cl_command_buffer_khr,
126    command_queue: cl_command_queue,
127    properties: *const cl_command_properties_khr,
128    sync_point_wait_list: &[cl_sync_point_khr],
129    sync_point: *mut cl_sync_point_khr,
130    mutable_handle: *mut cl_mutable_command_khr,
131) -> Result<(), cl_int> {
132    let status: cl_int = cl_call!(clCommandBarrierWithWaitListKHR(
133        command_buffer,
134        command_queue,
135        properties,
136        sync_point_wait_list.len() as cl_uint,
137        sync_point_wait_list.as_ptr(),
138        sync_point,
139        mutable_handle,
140    ));
141    if CL_SUCCESS == status {
142        Ok(())
143    } else {
144        Err(status)
145    }
146}
147
148#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
149#[allow(clippy::cast_possible_truncation)]
150pub unsafe fn command_copy_buffer_khr(
151    command_buffer: cl_command_buffer_khr,
152    command_queue: cl_command_queue,
153    properties: *const cl_command_properties_khr,
154    src_buffer: cl_mem,
155    dst_buffer: cl_mem,
156    src_offset: size_t,
157    dst_offset: size_t,
158    size: size_t,
159    sync_point_wait_list: &[cl_sync_point_khr],
160    sync_point: *mut cl_sync_point_khr,
161    mutable_handle: *mut cl_mutable_command_khr,
162) -> Result<(), cl_int> {
163    let status: cl_int = cl_call!(clCommandCopyBufferKHR(
164        command_buffer,
165        command_queue,
166        properties,
167        src_buffer,
168        dst_buffer,
169        src_offset,
170        dst_offset,
171        size,
172        sync_point_wait_list.len() as cl_uint,
173        sync_point_wait_list.as_ptr(),
174        sync_point,
175        mutable_handle,
176    ));
177    if CL_SUCCESS == status {
178        Ok(())
179    } else {
180        Err(status)
181    }
182}
183
184#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
185#[allow(clippy::cast_possible_truncation)]
186pub unsafe fn command_copy_buffer_rect_khr(
187    command_buffer: cl_command_buffer_khr,
188    command_queue: cl_command_queue,
189    properties: *const cl_command_properties_khr,
190    src_buffer: cl_mem,
191    dst_buffer: cl_mem,
192    src_origin: *const size_t,
193    dst_origin: *const size_t,
194    region: *const size_t,
195    src_row_pitch: size_t,
196    src_slice_pitch: size_t,
197    dst_row_pitch: size_t,
198    dst_slice_pitch: size_t,
199    sync_point_wait_list: &[cl_sync_point_khr],
200    sync_point: *mut cl_sync_point_khr,
201    mutable_handle: *mut cl_mutable_command_khr,
202) -> Result<(), cl_int> {
203    let status: cl_int = cl_call!(clCommandCopyBufferRectKHR(
204        command_buffer,
205        command_queue,
206        properties,
207        src_buffer,
208        dst_buffer,
209        src_origin,
210        dst_origin,
211        region,
212        src_row_pitch,
213        src_slice_pitch,
214        dst_row_pitch,
215        dst_slice_pitch,
216        sync_point_wait_list.len() as cl_uint,
217        sync_point_wait_list.as_ptr(),
218        sync_point,
219        mutable_handle,
220    ));
221    if CL_SUCCESS == status {
222        Ok(())
223    } else {
224        Err(status)
225    }
226}
227
228#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
229#[allow(clippy::cast_possible_truncation)]
230pub unsafe fn command_copy_buffer_to_image_khr(
231    command_buffer: cl_command_buffer_khr,
232    command_queue: cl_command_queue,
233    properties: *const cl_command_properties_khr,
234    src_buffer: cl_mem,
235    dst_image: cl_mem,
236    src_offset: size_t,
237    dst_origin: *const size_t,
238    region: *const size_t,
239    sync_point_wait_list: &[cl_sync_point_khr],
240    sync_point: *mut cl_sync_point_khr,
241    mutable_handle: *mut cl_mutable_command_khr,
242) -> Result<(), cl_int> {
243    let status: cl_int = cl_call!(clCommandCopyBufferToImageKHR(
244        command_buffer,
245        command_queue,
246        properties,
247        src_buffer,
248        dst_image,
249        src_offset,
250        dst_origin,
251        region,
252        sync_point_wait_list.len() as cl_uint,
253        sync_point_wait_list.as_ptr(),
254        sync_point,
255        mutable_handle,
256    ));
257    if CL_SUCCESS == status {
258        Ok(())
259    } else {
260        Err(status)
261    }
262}
263
264#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
265#[allow(clippy::cast_possible_truncation)]
266pub unsafe fn command_copy_image_khr(
267    command_buffer: cl_command_buffer_khr,
268    command_queue: cl_command_queue,
269    properties: *const cl_command_properties_khr,
270    src_image: cl_mem,
271    dst_image: cl_mem,
272    src_origin: *const size_t,
273    dst_origin: *const size_t,
274    region: *const size_t,
275    sync_point_wait_list: &[cl_sync_point_khr],
276    sync_point: *mut cl_sync_point_khr,
277    mutable_handle: *mut cl_mutable_command_khr,
278) -> Result<(), cl_int> {
279    let status: cl_int = cl_call!(clCommandCopyImageKHR(
280        command_buffer,
281        command_queue,
282        properties,
283        src_image,
284        dst_image,
285        src_origin,
286        dst_origin,
287        region,
288        sync_point_wait_list.len() as cl_uint,
289        sync_point_wait_list.as_ptr(),
290        sync_point,
291        mutable_handle,
292    ));
293    if CL_SUCCESS == status {
294        Ok(())
295    } else {
296        Err(status)
297    }
298}
299
300#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
301#[allow(clippy::cast_possible_truncation)]
302pub unsafe fn command_copy_image_to_buffer_khr(
303    command_buffer: cl_command_buffer_khr,
304    command_queue: cl_command_queue,
305    properties: *const cl_command_properties_khr,
306    src_image: cl_mem,
307    dst_buffer: cl_mem,
308    src_origin: *const size_t,
309    region: *const size_t,
310    dst_offset: size_t,
311    sync_point_wait_list: &[cl_sync_point_khr],
312    sync_point: *mut cl_sync_point_khr,
313    mutable_handle: *mut cl_mutable_command_khr,
314) -> Result<(), cl_int> {
315    let status: cl_int = cl_call!(clCommandCopyImageToBufferKHR(
316        command_buffer,
317        command_queue,
318        properties,
319        src_image,
320        dst_buffer,
321        src_origin,
322        region,
323        dst_offset,
324        sync_point_wait_list.len() as cl_uint,
325        sync_point_wait_list.as_ptr(),
326        sync_point,
327        mutable_handle,
328    ));
329    if CL_SUCCESS == status {
330        Ok(())
331    } else {
332        Err(status)
333    }
334}
335
336#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
337#[allow(clippy::cast_possible_truncation)]
338pub unsafe fn command_fill_buffer_khr(
339    command_buffer: cl_command_buffer_khr,
340    command_queue: cl_command_queue,
341    properties: *const cl_command_properties_khr,
342    buffer: cl_mem,
343    pattern: *const c_void,
344    pattern_size: size_t,
345    offset: size_t,
346    size: size_t,
347    sync_point_wait_list: &[cl_sync_point_khr],
348    sync_point: *mut cl_sync_point_khr,
349    mutable_handle: *mut cl_mutable_command_khr,
350) -> Result<(), cl_int> {
351    let status: cl_int = cl_call!(clCommandFillBufferKHR(
352        command_buffer,
353        command_queue,
354        properties,
355        buffer,
356        pattern,
357        pattern_size,
358        offset,
359        size,
360        sync_point_wait_list.len() as cl_uint,
361        sync_point_wait_list.as_ptr(),
362        sync_point,
363        mutable_handle,
364    ));
365    if CL_SUCCESS == status {
366        Ok(())
367    } else {
368        Err(status)
369    }
370}
371
372#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
373#[allow(clippy::cast_possible_truncation)]
374pub unsafe fn command_fill_image_khr(
375    command_buffer: cl_command_buffer_khr,
376    command_queue: cl_command_queue,
377    properties: *const cl_command_properties_khr,
378    image: cl_mem,
379    fill_color: *const c_void,
380    origin: *const size_t,
381    region: *const size_t,
382    sync_point_wait_list: &[cl_sync_point_khr],
383    sync_point: *mut cl_sync_point_khr,
384    mutable_handle: *mut cl_mutable_command_khr,
385) -> Result<(), cl_int> {
386    let status: cl_int = cl_call!(clCommandFillImageKHR(
387        command_buffer,
388        command_queue,
389        properties,
390        image,
391        fill_color,
392        origin,
393        region,
394        sync_point_wait_list.len() as cl_uint,
395        sync_point_wait_list.as_ptr(),
396        sync_point,
397        mutable_handle,
398    ));
399    if CL_SUCCESS == status {
400        Ok(())
401    } else {
402        Err(status)
403    }
404}
405
406#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
407#[allow(clippy::cast_possible_truncation)]
408pub unsafe fn command_nd_range_kernel_khr(
409    command_buffer: cl_command_buffer_khr,
410    command_queue: cl_command_queue,
411    properties: *const cl_command_properties_khr,
412    kernel: cl_kernel,
413    work_dim: cl_uint,
414    global_work_offset: *const size_t,
415    global_work_size: *const size_t,
416    local_work_size: *const size_t,
417    sync_point_wait_list: &[cl_sync_point_khr],
418    sync_point: *mut cl_sync_point_khr,
419    mutable_handle: *mut cl_mutable_command_khr,
420) -> Result<(), cl_int> {
421    let status: cl_int = cl_call!(clCommandNDRangeKernelKHR(
422        command_buffer,
423        command_queue,
424        properties,
425        kernel,
426        work_dim,
427        global_work_offset,
428        global_work_size,
429        local_work_size,
430        sync_point_wait_list.len() as cl_uint,
431        sync_point_wait_list.as_ptr(),
432        sync_point,
433        mutable_handle,
434    ));
435    if CL_SUCCESS == status {
436        Ok(())
437    } else {
438        Err(status)
439    }
440}
441
442#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
443#[allow(clippy::cast_possible_truncation)]
444pub unsafe fn command_svm_memcpy_khr(
445    command_buffer: cl_command_buffer_khr,
446    command_queue: cl_command_queue,
447    properties: *const cl_command_properties_khr,
448    dst_ptr: *mut c_void,
449    src_ptr: *const c_void,
450    size: size_t,
451    sync_point_wait_list: &[cl_sync_point_khr],
452    sync_point: *mut cl_sync_point_khr,
453    mutable_handle: *mut cl_mutable_command_khr,
454) -> Result<(), cl_int> {
455    let status: cl_int = cl_call!(clCommandSVMMemcpyKHR(
456        command_buffer,
457        command_queue,
458        properties,
459        dst_ptr,
460        src_ptr,
461        size,
462        sync_point_wait_list.len() as cl_uint,
463        sync_point_wait_list.as_ptr(),
464        sync_point,
465        mutable_handle,
466    ));
467    if CL_SUCCESS == status {
468        Ok(())
469    } else {
470        Err(status)
471    }
472}
473
474#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
475#[allow(clippy::cast_possible_truncation)]
476pub unsafe fn command_svm_mem_fill_khr(
477    command_buffer: cl_command_buffer_khr,
478    command_queue: cl_command_queue,
479    properties: *const cl_command_properties_khr,
480    svm_ptr: *mut c_void,
481    pattern: *const c_void,
482    pattern_size: size_t,
483    size: size_t,
484    sync_point_wait_list: &[cl_sync_point_khr],
485    sync_point: *mut cl_sync_point_khr,
486    mutable_handle: *mut cl_mutable_command_khr,
487) -> Result<(), cl_int> {
488    let status: cl_int = cl_call!(clCommandSVMMemFillKHR(
489        command_buffer,
490        command_queue,
491        properties,
492        svm_ptr,
493        pattern,
494        pattern_size,
495        size,
496        sync_point_wait_list.len() as cl_uint,
497        sync_point_wait_list.as_ptr(),
498        sync_point,
499        mutable_handle,
500    ));
501    if CL_SUCCESS == status {
502        Ok(())
503    } else {
504        Err(status)
505    }
506}
507
508#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
509pub fn get_command_buffer_data_khr(
510    command_buffer: cl_command_buffer_khr,
511    param_name: cl_command_buffer_info_khr,
512) -> Result<Vec<u8>, cl_int> {
513    api_info_size!(get_size, clGetCommandBufferInfoKHR);
514    let size = get_size(command_buffer, param_name)?;
515    api_info_vector!(get_vector, u8, clGetCommandBufferInfoKHR);
516    get_vector(command_buffer, param_name, size)
517}
518
519#[cfg(any(feature = "cl_khr_command_buffer", feature = "dynamic"))]
520pub fn get_command_buffer_info_khr(
521    command_queue: cl_command_buffer_khr,
522    param_name: cl_command_buffer_info_khr,
523) -> Result<InfoType, cl_int> {
524    match param_name {
525        CL_COMMAND_BUFFER_NUM_QUEUES_KHR
526        | CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR
527        | CL_COMMAND_BUFFER_STATE_KHR => {
528            api_info_value!(get_value, cl_uint, clGetCommandBufferInfoKHR);
529            Ok(InfoType::Uint(get_value(command_queue, param_name)?))
530        }
531
532        CL_COMMAND_BUFFER_PROPERTIES_ARRAY_KHR => {
533            api_info_size!(get_size, clGetCommandBufferInfoKHR);
534            api_info_vector!(
535                get_vec,
536                cl_command_buffer_properties_khr,
537                clGetCommandBufferInfoKHR
538            );
539            let size = get_size(command_queue, param_name)?;
540            Ok(InfoType::VecUlong(get_vec(
541                command_queue,
542                param_name,
543                size,
544            )?))
545        }
546
547        CL_COMMAND_BUFFER_QUEUES_KHR => {
548            api_info_size!(get_size, clGetCommandBufferInfoKHR);
549            api_info_vector!(get_vec, intptr_t, clGetCommandBufferInfoKHR);
550            let size = get_size(command_queue, param_name)?;
551            Ok(InfoType::VecIntPtr(get_vec(
552                command_queue,
553                param_name,
554                size,
555            )?))
556        }
557
558        _ => Ok(InfoType::VecUchar(get_command_buffer_data_khr(
559            command_queue,
560            param_name,
561        )?)),
562    }
563}
564
565#[cfg(any(feature = "cl_khr_command_buffer_multi_device", feature = "dynamic"))]
566pub unsafe fn remap_command_buffer_khr(
567    command_buffer: cl_command_buffer_khr,
568    automatic: cl_bool,
569    num_queues: cl_uint,
570    queues: *const cl_command_queue,
571    num_handles: cl_uint,
572    handles: *const cl_mutable_command_khr,
573    handles_ret: *mut cl_mutable_command_khr,
574) -> Result<cl_command_buffer_khr, cl_int> {
575    let mut errcode_ret: cl_int = CL_INVALID_VALUE;
576    let cmd_buffer = cl_call!(clRemapCommandBufferKHR(
577        command_buffer,
578        automatic,
579        num_queues,
580        queues,
581        num_handles,
582        handles,
583        handles_ret,
584        &raw mut errcode_ret,
585    ));
586    if CL_SUCCESS == errcode_ret {
587        Ok(cmd_buffer)
588    } else {
589        Err(errcode_ret)
590    }
591}
592
593#[cfg(any(
594    feature = "cl_khr_command_buffer_mutable_dispatch",
595    feature = "dynamic"
596))]
597pub unsafe fn update_mutable_commands_khr(
598    command_buffer: cl_command_buffer_khr,
599    num_configs: cl_uint,
600    config_types: *const cl_command_buffer_update_type_khr,
601    configs: *mut *const c_void,
602) -> Result<(), cl_int> {
603    let status: cl_int = cl_call!(clUpdateMutableCommandsKHR(
604        command_buffer,
605        num_configs,
606        config_types,
607        configs
608    ));
609    if CL_SUCCESS == status {
610        Ok(())
611    } else {
612        Err(status)
613    }
614}
615
616#[cfg(any(
617    feature = "cl_khr_command_buffer_mutable_dispatch",
618    feature = "dynamic"
619))]
620pub fn get_command_buffer_mutable_dispatch_data(
621    command: cl_mutable_command_khr,
622    param_name: cl_mutable_command_info_khr,
623) -> Result<Vec<u8>, cl_int> {
624    api_info_size!(get_size, clGetMutableCommandInfoKHR);
625    let size = get_size(command, param_name)?;
626    api_info_vector!(get_vector, u8, clGetMutableCommandInfoKHR);
627    get_vector(command, param_name, size)
628}
629
630#[cfg(any(feature = "cl_apple_setmemobjectdestructor", feature = "dynamic"))]
631pub unsafe fn set_mem_object_destructor_apple(
632    memobj: cl_mem,
633    pfn_notify: Option<unsafe extern "C" fn(cl_context, *mut c_void)>,
634    user_data: *mut c_void,
635) -> Result<(), cl_int> {
636    let status: cl_int = cl_call!(clSetMemObjectDestructorAPPLE(memobj, pfn_notify, user_data));
637    if CL_SUCCESS == status {
638        Ok(())
639    } else {
640        Err(status)
641    }
642}
643
644#[cfg(any(feature = "cl_khr_icd", feature = "dynamic"))]
645#[allow(clippy::uninit_vec)]
646pub fn icd_get_platform_ids_khr() -> Result<Vec<cl_platform_id>, cl_int> {
647    // Get the number of platforms
648    let mut count: cl_uint = 0;
649    let mut status =
650        unsafe { cl_call!(clIcdGetPlatformIDsKHR(0, ptr::null_mut(), &raw mut count)) };
651
652    if CL_SUCCESS != status {
653        Err(status)
654    } else if 0 < count {
655        // Get the platform ids.
656        let len = count as usize;
657        let mut ids: Vec<cl_platform_id> = Vec::with_capacity(len);
658        unsafe {
659            ids.set_len(len);
660            status = cl_call!(clIcdGetPlatformIDsKHR(
661                count,
662                ids.as_mut_ptr(),
663                ptr::null_mut()
664            ));
665        };
666
667        if CL_SUCCESS == status {
668            Ok(ids)
669        } else {
670            Err(status)
671        }
672    } else {
673        Ok(Vec::default())
674    }
675}
676
677#[cfg(any(feature = "cl_khr_icd", feature = "dynamic"))]
678pub fn icd_get_function_address_for_platform_khr(
679    platform: cl_platform_id,
680    func_name: *const c_char,
681) -> Result<*mut c_void, cl_int> {
682    let ptr = unsafe { cl_call!(clIcdGetFunctionAddressForPlatformKHR(platform, func_name)) };
683    if ptr.is_null() {
684        Err(DLOPEN_FUNCTION_NOT_AVAILABLE)
685    } else {
686        Ok(ptr)
687    }
688}
689
690#[cfg(any(feature = "cl_khr_icd", feature = "dynamic"))]
691pub fn icd_set_platform_dispatch_data_khr(
692    platform: cl_platform_id,
693    dispatch_data: *mut c_void,
694) -> Result<(), cl_int> {
695    let status = unsafe { cl_call!(clIcdSetPlatformDispatchDataKHR(platform, dispatch_data)) };
696    if CL_SUCCESS == status {
697        Ok(())
698    } else {
699        Err(status)
700    }
701}
702
703#[cfg(any(feature = "cl_khr_il_program", feature = "dynamic"))]
704pub fn create_program_with_il_khr(context: cl_context, il: &[u8]) -> Result<cl_program, cl_int> {
705    let mut status: cl_int = CL_INVALID_VALUE;
706    let program = unsafe {
707        cl_call!(clCreateProgramWithILKHR(
708            context,
709            il.as_ptr().cast::<c_void>(),
710            il.len() as size_t,
711            &raw mut status,
712        ))
713    };
714    if CL_SUCCESS == status {
715        Ok(program)
716    } else {
717        Err(status)
718    }
719}
720
721#[cfg(any(feature = "cl_khr_terminate_context", feature = "dynamic"))]
722pub unsafe fn terminate_context_khr(context: cl_context) -> Result<(), cl_int> {
723    let status = cl_call!(clTerminateContextKHR(context));
724    if CL_SUCCESS == status {
725        Ok(())
726    } else {
727        Err(status)
728    }
729}
730
731#[cfg(any(feature = "cl_khr_create_command_queue", feature = "dynamic"))]
732pub fn create_command_queue_with_properties_khr(
733    context: cl_context,
734    device: cl_device_id,
735    properties: *const cl_queue_properties_khr,
736) -> Result<cl_command_queue, cl_int> {
737    let mut status: cl_int = CL_INVALID_VALUE;
738    let queue: cl_command_queue = unsafe {
739        cl_call!(clCreateCommandQueueWithPropertiesKHR(
740            context,
741            device,
742            properties,
743            &raw mut status
744        ))
745    };
746    if CL_SUCCESS == status {
747        Ok(queue)
748    } else {
749        Err(status)
750    }
751}
752
753#[cfg(any(feature = "cl_ext_device_fission", feature = "dynamic"))]
754pub unsafe fn release_device_ext(device: cl_device_id) -> Result<(), cl_int> {
755    let status = cl_call!(clReleaseDeviceEXT(device));
756    if CL_SUCCESS == status {
757        Ok(())
758    } else {
759        Err(status)
760    }
761}
762
763#[cfg(any(feature = "cl_ext_device_fission", feature = "dynamic"))]
764pub unsafe fn retain_device_ext(device: cl_device_id) -> Result<(), cl_int> {
765    let status = cl_call!(clRetainDeviceEXT(device));
766    if CL_SUCCESS == status {
767        Ok(())
768    } else {
769        Err(status)
770    }
771}
772
773// helper function for create_sub_devices_ext
774#[cfg(any(feature = "cl_ext_device_fission", feature = "dynamic"))]
775fn count_sub_devices_ext(
776    in_device: cl_device_id,
777    properties: &[cl_device_partition_property_ext],
778) -> Result<cl_uint, cl_int> {
779    let mut count: cl_uint = 0;
780    let status: cl_int = unsafe {
781        cl_call!(clCreateSubDevicesEXT(
782            in_device,
783            properties.as_ptr(),
784            0,
785            ptr::null_mut(),
786            &raw mut count,
787        ))
788    };
789    if CL_SUCCESS == status {
790        Ok(count)
791    } else {
792        Err(status)
793    }
794}
795
796#[cfg(any(feature = "cl_ext_device_fission", feature = "dynamic"))]
797#[allow(clippy::cast_possible_truncation)]
798pub fn create_sub_devices_ext(
799    in_device: cl_device_id,
800    properties: &[cl_device_partition_property_ext],
801) -> Result<Vec<cl_device_id>, cl_int> {
802    // get the number of partitions
803    let num_devices: cl_uint = count_sub_devices_ext(in_device, properties)?;
804
805    // partition in_device
806    let mut ids: Vec<cl_device_id> = Vec::with_capacity(num_devices as usize);
807    let status: cl_int = unsafe {
808        ids.set_len(num_devices as usize);
809        cl_call!(clCreateSubDevicesEXT(
810            in_device,
811            properties.as_ptr(),
812            num_devices * mem::size_of::<cl_device_id>() as cl_uint,
813            ids.as_mut_ptr(),
814            ptr::null_mut(),
815        ))
816    };
817
818    if CL_SUCCESS == status {
819        Ok(ids)
820    } else {
821        Err(status)
822    }
823}
824
825#[cfg(any(feature = "cl_ext_migrate_memobject", feature = "dynamic"))]
826pub unsafe fn enqueue_migrate_mem_object_ext(
827    command_queue: cl_command_queue,
828    num_mem_objects: cl_uint,
829    mem_objects: *const cl_mem,
830    flags: cl_mem_migration_flags_ext,
831    num_events_in_wait_list: cl_uint,
832    event_wait_list: *const cl_event,
833) -> Result<cl_event, cl_int> {
834    let mut event: cl_event = ptr::null_mut();
835    let status: cl_int = cl_call!(clEnqueueMigrateMemObjectEXT(
836        command_queue,
837        num_mem_objects,
838        mem_objects,
839        flags,
840        num_events_in_wait_list,
841        event_wait_list,
842        &raw mut event,
843    ));
844    if CL_SUCCESS == status {
845        Ok(event)
846    } else {
847        Err(status)
848    }
849}
850
851#[cfg(any(feature = "cl_qcom_ext_host_ptr", feature = "dynamic"))]
852pub fn get_device_image_info_qcom(
853    device: cl_device_id,
854    image_width: size_t,
855    image_height: size_t,
856    image_format: *const cl_image_format,
857    param_name: cl_image_pitch_info_qcom,
858) -> Result<cl_uint, cl_int> {
859    let mut data: cl_uint = 0;
860    let data_ptr: *mut cl_uint = &raw mut data;
861    let status = unsafe {
862        cl_call!(clGetDeviceImageInfoQCOM(
863            device,
864            image_width,
865            image_height,
866            image_format,
867            param_name,
868            mem::size_of::<cl_uint>(),
869            data_ptr.cast::<c_void>(),
870            ptr::null_mut(),
871        ))
872    };
873    if CL_SUCCESS == status {
874        Ok(data)
875    } else {
876        Err(status)
877    }
878}
879
880#[cfg(any(feature = "cl_img_use_gralloc_ptr", feature = "dynamic"))]
881pub unsafe fn enqueue_acquire_gralloc_objects_img(
882    command_queue: cl_command_queue,
883    num_objects: cl_uint,
884    mem_objects: *const cl_mem,
885    num_events_in_wait_list: cl_uint,
886    event_wait_list: *const cl_event,
887) -> Result<cl_event, cl_int> {
888    let mut event: cl_event = ptr::null_mut();
889    let status: cl_int = cl_call!(clEnqueueAcquireGrallocObjectsIMG(
890        command_queue,
891        num_objects,
892        mem_objects,
893        num_events_in_wait_list,
894        event_wait_list,
895        &raw mut event,
896    ));
897    if CL_SUCCESS == status {
898        Ok(event)
899    } else {
900        Err(status)
901    }
902}
903
904#[cfg(any(feature = "cl_img_use_gralloc_ptr", feature = "dynamic"))]
905pub unsafe fn enqueue_release_gralloc_objects_img(
906    command_queue: cl_command_queue,
907    num_objects: cl_uint,
908    mem_objects: *const cl_mem,
909    num_events_in_wait_list: cl_uint,
910    event_wait_list: *const cl_event,
911) -> Result<cl_event, cl_int> {
912    let mut event: cl_event = ptr::null_mut();
913    let status: cl_int = cl_call!(clEnqueueReleaseGrallocObjectsIMG(
914        command_queue,
915        num_objects,
916        mem_objects,
917        num_events_in_wait_list,
918        event_wait_list,
919        &raw mut event,
920    ));
921    if CL_SUCCESS == status {
922        Ok(event)
923    } else {
924        Err(status)
925    }
926}
927
928#[cfg(any(feature = "cl_img_generate_mipmap", feature = "dynamic"))]
929pub unsafe fn enqueue_generate_mipmap_img(
930    command_queue: cl_command_queue,
931    src_image: cl_mem,
932    dst_image: cl_mem,
933    mipmap_filter_mode: cl_mipmap_filter_mode_img,
934    array_region: *const size_t,
935    mip_region: *const size_t,
936    num_events_in_wait_list: cl_uint,
937    event_wait_list: *const cl_event,
938) -> Result<cl_event, cl_int> {
939    let mut event: cl_event = ptr::null_mut();
940    let status: cl_int = cl_call!(clEnqueueGenerateMipmapIMG(
941        command_queue,
942        src_image,
943        dst_image,
944        mipmap_filter_mode,
945        array_region,
946        mip_region,
947        num_events_in_wait_list,
948        event_wait_list,
949        &raw mut event,
950    ));
951    if CL_SUCCESS == status {
952        Ok(event)
953    } else {
954        Err(status)
955    }
956}
957
958#[cfg(any(feature = "cl_khr_subgroups", feature = "dynamic"))]
959pub fn get_kernel_sub_group_info_khr(
960    kernel: cl_kernel,
961    device: cl_device_id,
962    param_name: cl_kernel_sub_group_info,
963    input_value_size: size_t,
964    input_value: *const c_void,
965) -> Result<size_t, cl_int> {
966    match param_name {
967        CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE_KHR
968        | CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR
969        | _ => {
970            // Assumes other cl_kernel_sub_group_info values return a size_t
971            // get the value
972            let mut data: size_t = 0;
973            let data_ptr: *mut size_t = &raw mut data;
974            let status = unsafe {
975                cl_call!(clGetKernelSubGroupInfoKHR(
976                    kernel,
977                    device,
978                    param_name,
979                    input_value_size,
980                    input_value,
981                    mem::size_of::<size_t>(),
982                    data_ptr.cast::<c_void>(),
983                    ptr::null_mut(),
984                ))
985            };
986            if CL_SUCCESS == status {
987                Ok(data)
988            } else {
989                Err(status)
990            }
991        }
992    }
993}
994
995#[cfg(any(feature = "cl_khr_suggested_local_work_size", feature = "dynamic"))]
996pub fn get_kernel_suggested_local_work_size_khr(
997    command_queue: cl_command_queue,
998    kernel: cl_kernel,
999    work_dim: cl_uint,
1000    global_work_offset: *const size_t,
1001    global_work_size: *const size_t,
1002) -> Result<size_t, cl_int> {
1003    let mut suggested_local_work_size: size_t = 0;
1004    let status: cl_int = unsafe {
1005        cl_call!(clGetKernelSuggestedLocalWorkSizeKHR(
1006            command_queue,
1007            kernel,
1008            work_dim,
1009            global_work_offset,
1010            global_work_size,
1011            &raw mut suggested_local_work_size,
1012        ))
1013    };
1014    if CL_SUCCESS == status {
1015        Ok(suggested_local_work_size)
1016    } else {
1017        Err(status)
1018    }
1019}
1020
1021#[cfg(any(feature = "cl_khr_external_memory", feature = "dynamic"))]
1022pub unsafe fn enqueue_acquire_external_mem_objects_khr(
1023    command_queue: cl_command_queue,
1024    num_mem_objects: cl_uint,
1025    mem_objects: *const cl_mem,
1026    num_events_in_wait_list: cl_uint,
1027    event_wait_list: *const cl_event,
1028) -> Result<cl_event, cl_int> {
1029    let mut event: cl_event = ptr::null_mut();
1030    let status: cl_int = cl_call!(clEnqueueAcquireExternalMemObjectsKHR(
1031        command_queue,
1032        num_mem_objects,
1033        mem_objects,
1034        num_events_in_wait_list,
1035        event_wait_list,
1036        &raw mut event,
1037    ));
1038    if CL_SUCCESS == status {
1039        Ok(event)
1040    } else {
1041        Err(status)
1042    }
1043}
1044
1045#[cfg(any(feature = "cl_khr_external_memory", feature = "dynamic"))]
1046pub unsafe fn enqueue_release_external_mem_objects_khr(
1047    command_queue: cl_command_queue,
1048    num_mem_objects: cl_uint,
1049    mem_objects: *const cl_mem,
1050    num_events_in_wait_list: cl_uint,
1051    event_wait_list: *const cl_event,
1052) -> Result<cl_event, cl_int> {
1053    let mut event: cl_event = ptr::null_mut();
1054    let status: cl_int = cl_call!(clEnqueueReleaseExternalMemObjectsKHR(
1055        command_queue,
1056        num_mem_objects,
1057        mem_objects,
1058        num_events_in_wait_list,
1059        event_wait_list,
1060        &raw mut event,
1061    ));
1062    if CL_SUCCESS == status {
1063        Ok(event)
1064    } else {
1065        Err(status)
1066    }
1067}
1068
1069#[cfg(any(feature = "cl_khr_external_semaphore", feature = "dynamic"))]
1070pub fn get_semaphore_handle_for_type_khr(
1071    sema_object: cl_semaphore_khr,
1072    device: cl_device_id,
1073    handle_type: cl_external_semaphore_handle_type_khr,
1074) -> Result<cl_semaphore_khr, cl_int> {
1075    // Get the size of the information.
1076    let mut size: size_t = 0;
1077    let status: cl_int = unsafe {
1078        cl_call!(clGetSemaphoreHandleForTypeKHR(
1079            sema_object,
1080            device,
1081            handle_type,
1082            0,
1083            ptr::null_mut(),
1084            &raw mut size,
1085        ))
1086    };
1087    if CL_SUCCESS == status {
1088        let mut data: cl_semaphore_khr = ptr::null_mut();
1089        let data_ptr: *mut cl_semaphore_khr = &raw mut data;
1090        let status: cl_int = unsafe {
1091            cl_call!(clGetSemaphoreHandleForTypeKHR(
1092                sema_object,
1093                device,
1094                handle_type,
1095                size,
1096                data_ptr.cast::<c_void>(),
1097                ptr::null_mut(),
1098            ))
1099        };
1100        if CL_SUCCESS == status {
1101            Ok(data)
1102        } else {
1103            Err(status)
1104        }
1105    } else {
1106        Err(status)
1107    }
1108}
1109
1110#[cfg(any(feature = "cl_khr_external_semaphore_sync_fd", feature = "dynamic"))]
1111pub unsafe fn reimport_semaphore_sync_fd(
1112    sema_object: cl_semaphore_khr,
1113    reimport_props: *mut cl_semaphore_reimport_properties_khr,
1114    fd: c_int,
1115) -> Result<(), cl_int> {
1116    let status: cl_int = cl_call!(clReImportSemaphoreSyncFdKHR(
1117        sema_object,
1118        reimport_props,
1119        fd
1120    ));
1121    if CL_SUCCESS == status {
1122        Ok(())
1123    } else {
1124        Err(status)
1125    }
1126}
1127
1128#[cfg(any(feature = "cl_khr_semaphore", feature = "dynamic"))]
1129pub fn create_semaphore_with_properties_khr(
1130    context: cl_context,
1131    sema_props: *const cl_semaphore_properties_khr,
1132) -> Result<cl_semaphore_khr, cl_int> {
1133    let mut status: cl_int = CL_INVALID_VALUE;
1134    let semaphore: cl_semaphore_khr = unsafe {
1135        cl_call!(clCreateSemaphoreWithPropertiesKHR(
1136            context,
1137            sema_props,
1138            &raw mut status
1139        ))
1140    };
1141    if CL_SUCCESS == status {
1142        Ok(semaphore)
1143    } else {
1144        Err(status)
1145    }
1146}
1147
1148#[cfg(any(feature = "cl_khr_semaphore", feature = "dynamic"))]
1149pub unsafe fn enqueue_wait_semaphores_khr(
1150    command_queue: cl_command_queue,
1151    num_sema_objects: cl_uint,
1152    sema_objects: *const cl_semaphore_khr,
1153    sema_payload_list: *const cl_semaphore_payload_khr,
1154    num_events_in_wait_list: cl_uint,
1155    event_wait_list: *const cl_event,
1156) -> Result<cl_event, cl_int> {
1157    let mut event: cl_event = ptr::null_mut();
1158    let status: cl_int = cl_call!(clEnqueueWaitSemaphoresKHR(
1159        command_queue,
1160        num_sema_objects,
1161        sema_objects,
1162        sema_payload_list,
1163        num_events_in_wait_list,
1164        event_wait_list,
1165        &raw mut event,
1166    ));
1167    if CL_SUCCESS == status {
1168        Ok(event)
1169    } else {
1170        Err(status)
1171    }
1172}
1173
1174#[cfg(any(feature = "cl_khr_semaphore", feature = "dynamic"))]
1175pub unsafe fn enqueue_signal_semaphores_khr(
1176    command_queue: cl_command_queue,
1177    num_sema_objects: cl_uint,
1178    sema_objects: *const cl_semaphore_khr,
1179    sema_payload_list: *const cl_semaphore_payload_khr,
1180    num_events_in_wait_list: cl_uint,
1181    event_wait_list: *const cl_event,
1182) -> Result<cl_event, cl_int> {
1183    let mut event: cl_event = ptr::null_mut();
1184    let status: cl_int = cl_call!(clEnqueueSignalSemaphoresKHR(
1185        command_queue,
1186        num_sema_objects,
1187        sema_objects,
1188        sema_payload_list,
1189        num_events_in_wait_list,
1190        event_wait_list,
1191        &raw mut event,
1192    ));
1193    if CL_SUCCESS == status {
1194        Ok(event)
1195    } else {
1196        Err(status)
1197    }
1198}
1199
1200#[cfg(any(feature = "cl_khr_semaphore", feature = "dynamic"))]
1201pub fn get_semaphore_info_khr(
1202    sema_object: cl_semaphore_khr,
1203    param_name: cl_semaphore_info_khr,
1204) -> Result<Vec<u8>, cl_int> {
1205    api_info_size!(get_size, clGetSemaphoreInfoKHR);
1206    let size = get_size(sema_object, param_name)?;
1207    api_info_vector!(get_vector, u8, clGetSemaphoreInfoKHR);
1208    get_vector(sema_object, param_name, size)
1209}
1210
1211#[cfg(any(feature = "cl_khr_semaphore", feature = "dynamic"))]
1212pub unsafe fn release_semaphore_khr(sema_object: cl_semaphore_khr) -> Result<(), cl_int> {
1213    let status: cl_int = cl_call!(clReleaseSemaphoreKHR(sema_object));
1214    if CL_SUCCESS == status {
1215        Ok(())
1216    } else {
1217        Err(status)
1218    }
1219}
1220
1221#[cfg(any(feature = "cl_khr_semaphore", feature = "dynamic"))]
1222pub unsafe fn retain_semaphore_khr(sema_object: cl_semaphore_khr) -> Result<(), cl_int> {
1223    let status: cl_int = cl_call!(clRetainSemaphoreKHR(sema_object));
1224    if CL_SUCCESS == status {
1225        Ok(())
1226    } else {
1227        Err(status)
1228    }
1229}
1230
1231#[cfg(any(feature = "cl_arm_import_memory", feature = "dynamic"))]
1232pub unsafe fn import_memory_arm(
1233    context: cl_context,
1234    flags: cl_mem_flags,
1235    properties: *const cl_import_properties_arm,
1236    memory: *mut c_void,
1237    size: size_t,
1238) -> Result<cl_mem, cl_int> {
1239    let mut status: cl_int = CL_INVALID_VALUE;
1240    let mem: cl_mem = cl_call!(clImportMemoryARM(
1241        context,
1242        flags,
1243        properties,
1244        memory,
1245        size,
1246        &raw mut status
1247    ));
1248    if CL_SUCCESS == status {
1249        Ok(mem)
1250    } else {
1251        Err(status)
1252    }
1253}
1254
1255#[cfg(any(feature = "cl_arm_shared_virtual_memory", feature = "dynamic"))]
1256pub unsafe fn svm_alloc_arm(
1257    context: cl_context,
1258    flags: cl_svm_mem_flags_arm,
1259    size: size_t,
1260    alignment: cl_uint,
1261) -> Result<*mut c_void, cl_int> {
1262    let ptr = cl_call!(clSVMAllocARM(context, flags, size, alignment));
1263    if ptr.is_null() {
1264        Err(CL_INVALID_VALUE)
1265    } else {
1266        Ok(ptr)
1267    }
1268}
1269
1270#[cfg(any(feature = "cl_arm_shared_virtual_memory", feature = "dynamic"))]
1271pub unsafe fn svm_free_arm(context: cl_context, svm_pointer: *mut c_void) -> Result<(), cl_int> {
1272    cl_call!(clSVMFreeARM(context, svm_pointer));
1273    Ok(())
1274}
1275
1276#[cfg(any(feature = "cl_arm_shared_virtual_memory", feature = "dynamic"))]
1277pub unsafe fn enqueue_svm_free_arm(
1278    command_queue: cl_command_queue,
1279    num_svm_pointers: cl_uint,
1280    svm_pointers: *mut *mut c_void,
1281    pfn_free_func: Option<
1282        unsafe extern "C" fn(
1283            queue: cl_command_queue,
1284            num_svm_pointers: cl_uint,
1285            svm_pointers: *mut *mut c_void,
1286            user_data: *mut c_void,
1287        ),
1288    >,
1289    user_data: *mut c_void,
1290    num_events_in_wait_list: cl_uint,
1291    event_wait_list: *const cl_event,
1292) -> Result<cl_event, cl_int> {
1293    let mut event: cl_event = ptr::null_mut();
1294    let status: cl_int = cl_call!(clEnqueueSVMFreeARM(
1295        command_queue,
1296        num_svm_pointers,
1297        svm_pointers,
1298        pfn_free_func,
1299        user_data,
1300        num_events_in_wait_list,
1301        event_wait_list,
1302        &raw mut event,
1303    ));
1304    if CL_SUCCESS == status {
1305        Ok(event)
1306    } else {
1307        Err(status)
1308    }
1309}
1310
1311#[cfg(any(feature = "cl_arm_shared_virtual_memory", feature = "dynamic"))]
1312pub unsafe fn enqueue_svm_mem_cpy_arm(
1313    command_queue: cl_command_queue,
1314    blocking_copy: cl_bool,
1315    dst_ptr: *mut c_void,
1316    src_ptr: *const c_void,
1317    size: size_t,
1318    num_events_in_wait_list: cl_uint,
1319    event_wait_list: *const cl_event,
1320) -> Result<cl_event, cl_int> {
1321    let mut event: cl_event = ptr::null_mut();
1322    let status: cl_int = cl_call!(clEnqueueSVMMemcpyARM(
1323        command_queue,
1324        blocking_copy,
1325        dst_ptr,
1326        src_ptr,
1327        size,
1328        num_events_in_wait_list,
1329        event_wait_list,
1330        &raw mut event,
1331    ));
1332    if CL_SUCCESS == status {
1333        Ok(event)
1334    } else {
1335        Err(status)
1336    }
1337}
1338
1339#[cfg(any(feature = "cl_arm_shared_virtual_memory", feature = "dynamic"))]
1340pub unsafe fn enqueue_svm_mem_fill_arm(
1341    command_queue: cl_command_queue,
1342    svm_ptr: *mut c_void,
1343    pattern: *const c_void,
1344    pattern_size: size_t,
1345    size: size_t,
1346    num_events_in_wait_list: cl_uint,
1347    event_wait_list: *const cl_event,
1348) -> Result<cl_event, cl_int> {
1349    let mut event: cl_event = ptr::null_mut();
1350    let status: cl_int = cl_call!(clEnqueueSVMMemFillARM(
1351        command_queue,
1352        svm_ptr,
1353        pattern,
1354        pattern_size,
1355        size,
1356        num_events_in_wait_list,
1357        event_wait_list,
1358        &raw mut event,
1359    ));
1360    if CL_SUCCESS == status {
1361        Ok(event)
1362    } else {
1363        Err(status)
1364    }
1365}
1366
1367#[cfg(any(feature = "cl_arm_shared_virtual_memory", feature = "dynamic"))]
1368pub unsafe fn enqueue_svm_map_arm(
1369    command_queue: cl_command_queue,
1370    blocking_map: cl_bool,
1371    flags: cl_map_flags,
1372    svm_ptr: *mut c_void,
1373    size: size_t,
1374    num_events_in_wait_list: cl_uint,
1375    event_wait_list: *const cl_event,
1376) -> Result<cl_event, cl_int> {
1377    let mut event: cl_event = ptr::null_mut();
1378    let status: cl_int = cl_call!(clEnqueueSVMMapARM(
1379        command_queue,
1380        blocking_map,
1381        flags,
1382        svm_ptr,
1383        size,
1384        num_events_in_wait_list,
1385        event_wait_list,
1386        &raw mut event,
1387    ));
1388    if CL_SUCCESS == status {
1389        Ok(event)
1390    } else {
1391        Err(status)
1392    }
1393}
1394
1395#[cfg(any(feature = "cl_arm_shared_virtual_memory", feature = "dynamic"))]
1396pub unsafe fn enqueue_svm_unmap_arm(
1397    command_queue: cl_command_queue,
1398    svm_ptr: *mut c_void,
1399    num_events_in_wait_list: cl_uint,
1400    event_wait_list: *const cl_event,
1401) -> Result<cl_event, cl_int> {
1402    let mut event: cl_event = ptr::null_mut();
1403    let status: cl_int = cl_call!(clEnqueueSVMUnmapARM(
1404        command_queue,
1405        svm_ptr,
1406        num_events_in_wait_list,
1407        event_wait_list,
1408        &raw mut event,
1409    ));
1410    if CL_SUCCESS == status {
1411        Ok(event)
1412    } else {
1413        Err(status)
1414    }
1415}
1416
1417#[cfg(any(feature = "cl_arm_shared_virtual_memory", feature = "dynamic"))]
1418pub fn set_kernel_arg_svm_pointer(
1419    kernel: cl_kernel,
1420    arg_index: cl_uint,
1421    arg_ptr: *const c_void,
1422) -> Result<(), cl_int> {
1423    let status: cl_int =
1424        unsafe { cl_call!(clSetKernelArgSVMPointerARM(kernel, arg_index, arg_ptr)) };
1425    if CL_SUCCESS == status {
1426        Ok(())
1427    } else {
1428        Err(status)
1429    }
1430}
1431
1432#[cfg(any(feature = "cl_arm_shared_virtual_memory", feature = "dynamic"))]
1433pub fn set_kernel_exec_info_arm(
1434    kernel: cl_kernel,
1435    param_name: cl_kernel_exec_info_arm,
1436    param_value_size: size_t,
1437    param_value: *const c_void,
1438) -> Result<(), cl_int> {
1439    let status: cl_int = unsafe {
1440        cl_call!(clSetKernelExecInfoARM(
1441            kernel,
1442            param_name,
1443            param_value_size,
1444            param_value
1445        ))
1446    };
1447    if CL_SUCCESS == status {
1448        Ok(())
1449    } else {
1450        Err(status)
1451    }
1452}
1453
1454#[cfg(any(feature = "cl_intel_accelerator", feature = "dynamic"))]
1455pub fn create_accelerator_intel(
1456    context: cl_context,
1457    accelerator_type: cl_accelerator_type_intel,
1458    descriptor_size: size_t,
1459    descriptor: *const c_void,
1460) -> Result<cl_accelerator_intel, cl_int> {
1461    let mut status: cl_int = CL_INVALID_VALUE;
1462    let ptr = unsafe {
1463        cl_call!(clCreateAcceleratorINTEL(
1464            context,
1465            accelerator_type,
1466            descriptor_size,
1467            descriptor,
1468            &raw mut status,
1469        ))
1470    };
1471    if CL_SUCCESS == status {
1472        Ok(ptr)
1473    } else {
1474        Err(status)
1475    }
1476}
1477
1478#[cfg(any(feature = "cl_intel_accelerator", feature = "dynamic"))]
1479pub fn get_accelerator_data_intel(
1480    accelerator: cl_accelerator_intel,
1481    param_name: cl_accelerator_info_intel,
1482) -> Result<Vec<u8>, cl_int> {
1483    api_info_size!(get_size, clGetAcceleratorInfoINTEL);
1484    let size = get_size(accelerator, param_name)?;
1485    api_info_vector!(get_vector, u8, clGetAcceleratorInfoINTEL);
1486    get_vector(accelerator, param_name, size)
1487}
1488
1489#[cfg(any(feature = "cl_intel_accelerator", feature = "dynamic"))]
1490pub fn get_accelerator_info_intel(
1491    accelerator: cl_accelerator_intel,
1492    param_name: cl_accelerator_info_intel,
1493) -> Result<InfoType, cl_int> {
1494    match param_name {
1495        CL_ACCELERATOR_REFERENCE_COUNT_INTEL | CL_ACCELERATOR_TYPE_INTEL => {
1496            api_info_value!(get_value, cl_uint, clGetAcceleratorInfoINTEL);
1497            Ok(InfoType::Uint(get_value(accelerator, param_name)?))
1498        }
1499        CL_ACCELERATOR_CONTEXT_INTEL => {
1500            api_info_value!(get_value, intptr_t, clGetAcceleratorInfoINTEL);
1501            Ok(InfoType::Ptr(get_value(accelerator, param_name)?))
1502        }
1503        CL_ACCELERATOR_DESCRIPTOR_INTEL
1504            // The complete descriptor structure supplied when the
1505            // accelerator was created.
1506        | _ => {
1507            Ok(InfoType::VecUchar(get_accelerator_data_intel(
1508                accelerator,
1509                param_name,
1510            )?))
1511        }
1512    }
1513}
1514
1515#[cfg(any(feature = "cl_intel_accelerator", feature = "dynamic"))]
1516pub unsafe fn retain_accelerator_intel(accelerator: cl_accelerator_intel) -> Result<(), cl_int> {
1517    let status = cl_call!(clRetainAcceleratorINTEL(accelerator));
1518    if CL_SUCCESS == status {
1519        Ok(())
1520    } else {
1521        Err(status)
1522    }
1523}
1524
1525#[cfg(any(feature = "cl_intel_accelerator", feature = "dynamic"))]
1526pub unsafe fn release_accelerator_intel(accelerator: cl_accelerator_intel) -> Result<(), cl_int> {
1527    let status = cl_call!(clReleaseAcceleratorINTEL(accelerator));
1528    if CL_SUCCESS == status {
1529        Ok(())
1530    } else {
1531        Err(status)
1532    }
1533}
1534
1535#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1536pub unsafe fn host_mem_alloc_intel(
1537    context: cl_context,
1538    properties: *const cl_mem_properties_intel,
1539    size: size_t,
1540    alignment: cl_uint,
1541) -> Result<(), cl_int> {
1542    let mut status: cl_int = CL_INVALID_VALUE;
1543    cl_call!(clHostMemAllocINTEL(
1544        context,
1545        properties,
1546        size,
1547        alignment,
1548        &raw mut status
1549    ));
1550    if CL_SUCCESS == status {
1551        Ok(())
1552    } else {
1553        Err(status)
1554    }
1555}
1556
1557#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1558pub unsafe fn device_mem_alloc_intel(
1559    context: cl_context,
1560    device: cl_device_id,
1561    properties: *const cl_mem_properties_intel,
1562    size: size_t,
1563    alignment: cl_uint,
1564) -> Result<(), cl_int> {
1565    let mut status: cl_int = CL_INVALID_VALUE;
1566    cl_call!(clDeviceMemAllocINTEL(
1567        context,
1568        device,
1569        properties,
1570        size,
1571        alignment,
1572        &raw mut status
1573    ));
1574    if CL_SUCCESS == status {
1575        Ok(())
1576    } else {
1577        Err(status)
1578    }
1579}
1580
1581#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1582pub unsafe fn shared_mem_alloc_intel(
1583    context: cl_context,
1584    device: cl_device_id,
1585    properties: *const cl_mem_properties_intel,
1586    size: size_t,
1587    alignment: cl_uint,
1588) -> Result<(), cl_int> {
1589    let mut status: cl_int = CL_INVALID_VALUE;
1590    cl_call!(clSharedMemAllocINTEL(
1591        context,
1592        device,
1593        properties,
1594        size,
1595        alignment,
1596        &raw mut status
1597    ));
1598    if CL_SUCCESS == status {
1599        Ok(())
1600    } else {
1601        Err(status)
1602    }
1603}
1604
1605#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1606pub unsafe fn mem_free_intel(context: cl_context, ptr: *mut c_void) -> Result<(), cl_int> {
1607    let status = cl_call!(clMemFreeINTEL(context, ptr));
1608    if CL_SUCCESS == status {
1609        Ok(())
1610    } else {
1611        Err(status)
1612    }
1613}
1614
1615#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1616pub unsafe fn mem_blocking_free_intel(context: cl_context, ptr: *mut c_void) -> Result<(), cl_int> {
1617    let status = cl_call!(clMemBlockingFreeINTEL(context, ptr));
1618    if CL_SUCCESS == status {
1619        Ok(())
1620    } else {
1621        Err(status)
1622    }
1623}
1624
1625#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1626fn mem_alloc_info_intel<T: Default>(
1627    context: cl_context,
1628    ptr: *const c_void,
1629    param_id: cl_mem_info_intel,
1630) -> Result<T, cl_int> {
1631    let mut data: T = T::default();
1632    let data_ptr: *mut T = &raw mut data;
1633    let status = unsafe {
1634        cl_call!(clGetMemAllocInfoINTEL(
1635            context,
1636            ptr,
1637            param_id,
1638            mem::size_of::<T>(),
1639            data_ptr.cast::<c_void>(),
1640            ptr::null_mut(),
1641        ))
1642    };
1643    if CL_SUCCESS == status {
1644        Ok(data)
1645    } else {
1646        Err(status)
1647    }
1648}
1649
1650#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1651pub fn get_mem_alloc_info_intel(
1652    context: cl_context,
1653    ptr: *const c_void,
1654    param_name: cl_mem_info_intel,
1655) -> Result<InfoType, cl_int> {
1656    match param_name {
1657        CL_MEM_ALLOC_TYPE_INTEL => Ok(InfoType::Uint(mem_alloc_info_intel::<
1658            cl_unified_shared_memory_type_intel,
1659        >(context, ptr, param_name)?)),
1660
1661        CL_MEM_ALLOC_BASE_PTR_INTEL | CL_MEM_ALLOC_DEVICE_INTEL => Ok(InfoType::Ptr(
1662            mem_alloc_info_intel::<intptr_t>(context, ptr, param_name)?,
1663        )),
1664
1665        CL_MEM_ALLOC_SIZE_INTEL => Ok(InfoType::Size(mem_alloc_info_intel::<size_t>(
1666            context, ptr, param_name,
1667        )?)),
1668
1669        _ => {
1670            // values 0x419E-0x419F are reserved for future queries
1671            // get the size
1672            let mut size: size_t = 0;
1673            let status = unsafe {
1674                cl_call!(clGetMemAllocInfoINTEL(
1675                    context,
1676                    ptr,
1677                    param_name,
1678                    0,
1679                    ptr::null_mut(),
1680                    &raw mut size
1681                ))
1682            };
1683            if CL_SUCCESS != status {
1684                Err(status)
1685            } else if 0 < size {
1686                // Get the data.
1687                let mut data: Vec<u8> = Vec::with_capacity(size);
1688                let status = unsafe {
1689                    cl_call!(clGetMemAllocInfoINTEL(
1690                        context,
1691                        ptr,
1692                        param_name,
1693                        size,
1694                        data.as_mut_ptr().cast::<c_void>(),
1695                        ptr::null_mut(),
1696                    ))
1697                };
1698                if CL_SUCCESS == status {
1699                    Ok(InfoType::VecUchar(data))
1700                } else {
1701                    Err(status)
1702                }
1703            } else {
1704                Ok(InfoType::VecUchar(Vec::default()))
1705            }
1706        }
1707    }
1708}
1709
1710#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1711pub unsafe fn set_kernel_arg_mem_pointer_intel(
1712    kernel: cl_kernel,
1713    arg_index: cl_uint,
1714    arg_value: *const c_void,
1715) -> Result<(), cl_int> {
1716    let status = cl_call!(clSetKernelArgMemPointerINTEL(kernel, arg_index, arg_value));
1717    if CL_SUCCESS == status {
1718        Ok(())
1719    } else {
1720        Err(status)
1721    }
1722}
1723
1724#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1725pub unsafe fn enqueue_mem_set_intel(
1726    command_queue: cl_command_queue,
1727    dst_ptr: *mut c_void,
1728    value: cl_int,
1729    size: size_t,
1730    num_events_in_wait_list: cl_uint,
1731    event_wait_list: *const cl_event,
1732) -> Result<cl_event, cl_int> {
1733    let mut event: cl_event = ptr::null_mut();
1734    let status: cl_int = cl_call!(clEnqueueMemsetINTEL(
1735        command_queue,
1736        dst_ptr,
1737        value,
1738        size,
1739        num_events_in_wait_list,
1740        event_wait_list,
1741        &raw mut event,
1742    ));
1743    if CL_SUCCESS == status {
1744        Ok(event)
1745    } else {
1746        Err(status)
1747    }
1748}
1749
1750#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1751pub unsafe fn enqueue_mem_fill_intel(
1752    command_queue: cl_command_queue,
1753    dst_ptr: *mut c_void,
1754    pattern: *const c_void,
1755    pattern_size: size_t,
1756    size: size_t,
1757    num_events_in_wait_list: cl_uint,
1758    event_wait_list: *const cl_event,
1759) -> Result<cl_event, cl_int> {
1760    let mut event: cl_event = ptr::null_mut();
1761    let status: cl_int = cl_call!(clEnqueueMemFillINTEL(
1762        command_queue,
1763        dst_ptr,
1764        pattern,
1765        pattern_size,
1766        size,
1767        num_events_in_wait_list,
1768        event_wait_list,
1769        &raw mut event,
1770    ));
1771    if CL_SUCCESS == status {
1772        Ok(event)
1773    } else {
1774        Err(status)
1775    }
1776}
1777
1778#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1779pub unsafe fn enqueue_mem_copy_intel(
1780    command_queue: cl_command_queue,
1781    blocking: cl_bool,
1782    dst_ptr: *mut c_void,
1783    src_ptr: *const c_void,
1784    size: size_t,
1785    num_events_in_wait_list: cl_uint,
1786    event_wait_list: *const cl_event,
1787) -> Result<cl_event, cl_int> {
1788    let mut event: cl_event = ptr::null_mut();
1789    let status: cl_int = cl_call!(clEnqueueMemcpyINTEL(
1790        command_queue,
1791        blocking,
1792        dst_ptr,
1793        src_ptr,
1794        size,
1795        num_events_in_wait_list,
1796        event_wait_list,
1797        &raw mut event,
1798    ));
1799    if CL_SUCCESS == status {
1800        Ok(event)
1801    } else {
1802        Err(status)
1803    }
1804}
1805
1806#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1807pub unsafe fn enqueue_migrate_mem_intel(
1808    command_queue: cl_command_queue,
1809    ptr: *const c_void,
1810    size: size_t,
1811    flags: cl_mem_migration_flags,
1812    num_events_in_wait_list: cl_uint,
1813    event_wait_list: *const cl_event,
1814) -> Result<cl_event, cl_int> {
1815    let mut event: cl_event = ptr::null_mut();
1816    let status: cl_int = cl_call!(clEnqueueMigrateMemINTEL(
1817        command_queue,
1818        ptr,
1819        size,
1820        flags,
1821        num_events_in_wait_list,
1822        event_wait_list,
1823        &raw mut event,
1824    ));
1825    if CL_SUCCESS == status {
1826        Ok(event)
1827    } else {
1828        Err(status)
1829    }
1830}
1831
1832#[cfg(any(feature = "cl_intel_unified_shared_memory", feature = "dynamic"))]
1833pub unsafe fn enqueue_mem_advise_intel(
1834    command_queue: cl_command_queue,
1835    ptr: *const c_void,
1836    size: size_t,
1837    advice: cl_mem_advice_intel,
1838    num_events_in_wait_list: cl_uint,
1839    event_wait_list: *const cl_event,
1840) -> Result<cl_event, cl_int> {
1841    let mut event: cl_event = ptr::null_mut();
1842    let status: cl_int = cl_call!(clEnqueueMemAdviseINTEL(
1843        command_queue,
1844        ptr,
1845        size,
1846        advice,
1847        num_events_in_wait_list,
1848        event_wait_list,
1849        &raw mut event,
1850    ));
1851    if CL_SUCCESS == status {
1852        Ok(event)
1853    } else {
1854        Err(status)
1855    }
1856}
1857
1858#[cfg(any(
1859    feature = "cl_intel_create_buffer_with_properties",
1860    feature = "dynamic"
1861))]
1862pub unsafe fn create_buffer_with_properties_intel(
1863    context: cl_context,
1864    properties: *const cl_mem_properties_intel,
1865    flags: cl_mem_flags,
1866    size: size_t,
1867    host_ptr: *mut c_void,
1868) -> Result<cl_mem, cl_int> {
1869    let mut status: cl_int = CL_INVALID_VALUE;
1870    let mem: cl_mem = cl_call!(clCreateBufferWithPropertiesINTEL(
1871        context,
1872        properties,
1873        flags,
1874        size,
1875        host_ptr,
1876        &raw mut status
1877    ));
1878    if CL_SUCCESS == status {
1879        Ok(mem)
1880    } else {
1881        Err(status)
1882    }
1883}
1884
1885#[cfg(any(feature = "cl_intel_program_scope_host_pipe", feature = "dynamic"))]
1886pub unsafe fn enqueue_read_host_pipe_intel(
1887    command_queue: cl_command_queue,
1888    program: cl_program,
1889    pipe_symbol: *const c_char,
1890    blocking_read: cl_bool,
1891    ptr: *mut c_void,
1892    size: size_t,
1893    num_events_in_wait_list: cl_uint,
1894    event_wait_list: *const cl_event,
1895) -> Result<cl_event, cl_int> {
1896    let mut event: cl_event = ptr::null_mut();
1897    let status: cl_int = cl_call!(clEnqueueReadHostPipeINTEL(
1898        command_queue,
1899        program,
1900        pipe_symbol,
1901        blocking_read,
1902        ptr,
1903        size,
1904        num_events_in_wait_list,
1905        event_wait_list,
1906        &raw mut event,
1907    ));
1908    if CL_SUCCESS == status {
1909        Ok(event)
1910    } else {
1911        Err(status)
1912    }
1913}
1914
1915#[cfg(any(feature = "cl_intel_program_scope_host_pipe", feature = "dynamic"))]
1916pub unsafe fn enqueue_write_host_pipe_intel(
1917    command_queue: cl_command_queue,
1918    program: cl_program,
1919    pipe_symbol: *const c_char,
1920    blocking_write: cl_bool,
1921    ptr: *const c_void,
1922    size: size_t,
1923    num_events_in_wait_list: cl_uint,
1924    event_wait_list: *const cl_event,
1925) -> Result<cl_event, cl_int> {
1926    let mut event: cl_event = ptr::null_mut();
1927    let status: cl_int = cl_call!(clEnqueueWriteHostPipeINTEL(
1928        command_queue,
1929        program,
1930        pipe_symbol,
1931        blocking_write,
1932        ptr,
1933        size,
1934        num_events_in_wait_list,
1935        event_wait_list,
1936        &raw mut event,
1937    ));
1938    if CL_SUCCESS == status {
1939        Ok(event)
1940    } else {
1941        Err(status)
1942    }
1943}
1944
1945#[cfg(any(feature = "cl_ext_image_requirements_info", feature = "dynamic"))]
1946pub fn get_image_requirements_info_ext(
1947    context: cl_context,
1948    properties: *const cl_mem_properties,
1949    flags: cl_mem_flags,
1950    image_format: *const cl_image_format,
1951    image_desc: *const cl_image_desc,
1952    param_name: cl_image_requirements_info_ext,
1953) -> Result<Vec<u8>, cl_int> {
1954    // get the size
1955    let mut size: size_t = mem::size_of::<u8>();
1956    let status: cl_int = unsafe {
1957        cl_call!(clGetImageRequirementsInfoEXT(
1958            context,
1959            properties,
1960            flags,
1961            image_format,
1962            image_desc,
1963            param_name,
1964            0,
1965            ptr::null_mut(),
1966            &raw mut size,
1967        ))
1968    };
1969    if CL_SUCCESS == status {
1970        // Get the data.
1971        let mut data: Vec<u8> = Vec::with_capacity(size);
1972        let status = unsafe {
1973            data.set_len(size);
1974            cl_call!(clGetImageRequirementsInfoEXT(
1975                context,
1976                properties,
1977                flags,
1978                image_format,
1979                image_desc,
1980                param_name,
1981                size,
1982                data.as_mut_ptr().cast::<c_void>(),
1983                ptr::null_mut(),
1984            ))
1985        };
1986        if CL_SUCCESS == status {
1987            Ok(data)
1988        } else {
1989            Err(status)
1990        }
1991    } else {
1992        Err(status)
1993    }
1994}
1995
1996#[cfg(any(feature = "cl_loader_info", feature = "dynamic"))]
1997pub fn get_icd_loader_info_oclicd(param_name: cl_icdl_info) -> Result<Vec<u8>, cl_int> {
1998    // get the size
1999    let mut size: size_t = 0;
2000    let status = unsafe {
2001        cl_call!(clGetICDLoaderInfoOCLICD(
2002            param_name,
2003            0,
2004            ptr::null_mut(),
2005            &raw mut size
2006        ))
2007    };
2008    if CL_SUCCESS == status {
2009        // Get the data.
2010        let mut data: Vec<u8> = Vec::with_capacity(size);
2011        let status = unsafe {
2012            cl_call!(clGetICDLoaderInfoOCLICD(
2013                param_name,
2014                size,
2015                data.as_mut_ptr().cast::<c_void>(),
2016                ptr::null_mut(),
2017            ))
2018        };
2019        if CL_SUCCESS == status {
2020            Ok(data)
2021        } else {
2022            Err(status)
2023        }
2024    } else {
2025        Err(status)
2026    }
2027}
2028
2029#[cfg(any(feature = "cl_pocl_content_size", feature = "dynamic"))]
2030pub fn set_content_size_buffer_pocl(
2031    buffer: cl_mem,
2032    content_size_buffer: cl_mem,
2033) -> Result<(), cl_int> {
2034    let status = unsafe { cl_call!(clSetContentSizeBufferPoCL(buffer, content_size_buffer)) };
2035    if CL_SUCCESS == status {
2036        Ok(())
2037    } else {
2038        Err(status)
2039    }
2040}
2041
2042#[cfg(any(feature = "cl_img_cancel_command", feature = "dynamic"))]
2043pub fn cancel_commands_img(
2044    event_list: *const cl_event,
2045    num_events_in_list: cl_uint,
2046) -> Result<(), cl_int> {
2047    let status = unsafe { cl_call!(clCancelCommandsIMG(event_list, num_events_in_list)) };
2048    if CL_SUCCESS == status {
2049        Ok(())
2050    } else {
2051        Err(status)
2052    }
2053}
2054
2055#[cfg(any(feature = "cl_qcom_perf_hint", feature = "dynamic"))]
2056pub fn set_perf_hint_qcom(context: cl_context, perf_hint: cl_perf_hint_qcom) -> Result<(), cl_int> {
2057    let status = unsafe { cl_call!(clSetPerfHintQCOM(context, perf_hint)) };
2058    if CL_SUCCESS == status {
2059        Ok(())
2060    } else {
2061        Err(status)
2062    }
2063}