cl3/memory.rs
1// Copyright (c) 2020-2025 Via Technology Ltd. All Rights Reserved.
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` Memory Object API.
16
17#![allow(unused_unsafe)]
18#![allow(non_camel_case_types)]
19#![allow(clippy::not_unsafe_ptr_arg_deref)]
20
21pub use opencl_sys::{
22 CL_A, CL_ABGR, CL_ADDRESS_CLAMP, CL_ADDRESS_CLAMP_TO_EDGE, CL_ADDRESS_MIRRORED_REPEAT,
23 CL_ADDRESS_NONE, CL_ADDRESS_REPEAT, CL_ARGB, CL_BGRA, CL_BUFFER_CREATE_TYPE_REGION, CL_DEPTH,
24 CL_FALSE, CL_FILTER_LINEAR, CL_FILTER_NEAREST, CL_FLOAT, CL_HALF_FLOAT, CL_IMAGE_ARRAY_SIZE,
25 CL_IMAGE_BUFFER, CL_IMAGE_DEPTH, CL_IMAGE_ELEMENT_SIZE, CL_IMAGE_FORMAT, CL_IMAGE_HEIGHT,
26 CL_IMAGE_NUM_MIP_LEVELS, CL_IMAGE_NUM_SAMPLES, CL_IMAGE_ROW_PITCH, CL_IMAGE_SLICE_PITCH,
27 CL_IMAGE_WIDTH, CL_INTENSITY, CL_INVALID_VALUE, CL_LUMINANCE, CL_MAP_READ, CL_MAP_WRITE,
28 CL_MAP_WRITE_INVALIDATE_REGION, CL_MEM_ALLOC_HOST_PTR, CL_MEM_ASSOCIATED_MEMOBJECT,
29 CL_MEM_CONTEXT, CL_MEM_COPY_HOST_PTR, CL_MEM_FLAGS, CL_MEM_HOST_NO_ACCESS, CL_MEM_HOST_PTR,
30 CL_MEM_HOST_READ_ONLY, CL_MEM_HOST_WRITE_ONLY, CL_MEM_KERNEL_READ_AND_WRITE, CL_MEM_MAP_COUNT,
31 CL_MEM_OBJECT_BUFFER, CL_MEM_OBJECT_IMAGE1D, CL_MEM_OBJECT_IMAGE1D_ARRAY,
32 CL_MEM_OBJECT_IMAGE1D_BUFFER, CL_MEM_OBJECT_IMAGE2D, CL_MEM_OBJECT_IMAGE2D_ARRAY,
33 CL_MEM_OBJECT_IMAGE3D, CL_MEM_OBJECT_PIPE, CL_MEM_OFFSET, CL_MEM_PROPERTIES, CL_MEM_READ_ONLY,
34 CL_MEM_READ_WRITE, CL_MEM_REFERENCE_COUNT, CL_MEM_SIZE, CL_MEM_SVM_ATOMICS,
35 CL_MEM_SVM_FINE_GRAIN_BUFFER, CL_MEM_TYPE, CL_MEM_USE_HOST_PTR, CL_MEM_USES_SVM_POINTER,
36 CL_MEM_WRITE_ONLY, CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED, CL_MIGRATE_MEM_OBJECT_HOST,
37 CL_PIPE_MAX_PACKETS, CL_PIPE_PACKET_SIZE, CL_PIPE_PROPERTIES, CL_R, CL_RA, CL_RG, CL_RGB,
38 CL_RGBA, CL_RGBx, CL_RGx, CL_Rx, CL_SIGNED_INT8, CL_SIGNED_INT16, CL_SIGNED_INT32,
39 CL_SNORM_INT8, CL_SNORM_INT16, CL_SUCCESS, CL_TRUE, CL_UNORM_INT_101010, CL_UNORM_INT_101010_2,
40 CL_UNORM_INT8, CL_UNORM_INT16, CL_UNORM_SHORT_555, CL_UNORM_SHORT_565, CL_UNSIGNED_INT8,
41 CL_UNSIGNED_INT16, CL_UNSIGNED_INT32, CL_sRGB, CL_sRGBA, CL_sRGBx, cl_buffer_create_type,
42 cl_buffer_region, cl_context, cl_image_desc, cl_image_format, cl_image_info, cl_int, cl_mem,
43 cl_mem_flags, cl_mem_info, cl_mem_object_type, cl_mem_properties, cl_pipe_info,
44 cl_svm_mem_flags, cl_uint, cl_ulong,
45};
46
47use super::info_type::InfoType;
48use super::{api_info_size, api_info_value, api_info_vector};
49use libc::{c_void, intptr_t, size_t};
50use std::mem;
51use std::ptr;
52
53/// Create an `OpenCL` buffer object for a `context`.
54/// Calls `clCreateBuffer` to create an `OpenCL` buffer object.
55///
56/// * `context` - a valid `OpenCL` context.
57/// * `flags` - a bit-field used to specify allocation and usage information
58/// about the image memory object being created, see:
59/// [Memory Flags](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#memory-flags-table).
60/// * `size` - the size in bytes of the buffer memory object to be allocated.
61/// * `host_ptr` - a pointer to the buffer data that may already be allocated
62/// by the application.
63///
64/// returns a Result containing the new `OpenCL` buffer object
65/// or the error code from the `OpenCL` C API function.
66///
67/// # Safety
68///
69/// This function is unsafe because incorrect `flags` can cause undefined behaviour.
70#[inline]
71pub unsafe fn create_buffer(
72 context: cl_context,
73 flags: cl_mem_flags,
74 size: size_t,
75 host_ptr: *mut c_void,
76) -> Result<cl_mem, cl_int> {
77 let mut status: cl_int = CL_INVALID_VALUE;
78 let mem: cl_mem = cl_call!(clCreateBuffer(
79 context,
80 flags,
81 size,
82 host_ptr,
83 &raw mut status
84 ));
85 if CL_SUCCESS == status {
86 Ok(mem)
87 } else {
88 Err(status)
89 }
90}
91
92/// Create an new `OpenCL` buffer object from an existing buffer object.
93/// Calls `clCreateSubBuffer` to create an `OpenCL` sub-buffer object.
94///
95/// * `buffer` - a valid `OpenCL` buffer.
96/// * `flags` - a bit-field used to specify allocation and usage information
97/// about the sub-buffer memory object being created, see:
98/// [Memory Flags](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#memory-flags-table).
99/// * `buffer_create_type`,`buffer_create_info` - describe the type of
100/// buffer object to be created, see:
101/// [SubBuffer Attributes](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#subbuffer-create-info-table).
102///
103/// returns a Result containing the new `OpenCL` buffer object
104/// or the error code from the `OpenCL` C API function.
105///
106/// # Safety
107///
108/// This function is unsafe because incorrect `flags` can cause undefined behaviour.
109#[inline]
110pub unsafe fn create_sub_buffer(
111 buffer: cl_mem,
112 flags: cl_mem_flags,
113 buffer_create_type: cl_buffer_create_type,
114 buffer_create_info: *const c_void,
115) -> Result<cl_mem, cl_int> {
116 let mut status: cl_int = CL_INVALID_VALUE;
117 let mem: cl_mem = cl_call!(clCreateSubBuffer(
118 buffer,
119 flags,
120 buffer_create_type,
121 buffer_create_info,
122 &raw mut status,
123 ));
124 if CL_SUCCESS == status {
125 Ok(mem)
126 } else {
127 Err(status)
128 }
129}
130
131/// Create an `OpenCL` image object for a `context`.
132/// Calls `clCreateImage` to create an `OpenCL` image object.
133///
134/// * `context` - a valid `OpenCL` context.
135/// * `flags` - a bit-field used to specify allocation and usage information
136/// about the image memory object being created, see:
137/// [Memory Flags](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#memory-flags-table).
138/// * `image_format` - a pointer to a structure that describes format properties
139/// of the image to be allocated.
140/// * `image_desc` - a pointer to a structure that describes type and dimensions
141/// of the image to be allocated.
142/// * `host_ptr` - a pointer to the image data that may already be allocated
143/// by the application.
144///
145/// returns a Result containing the new `OpenCL` image object
146/// or the error code from the `OpenCL` C API function.
147///
148/// # Safety
149///
150/// This function is unsafe because incorrect `flags` can cause undefined behaviour.
151#[cfg(any(feature = "CL_VERSION_1_2", feature = "dynamic"))]
152#[inline]
153pub unsafe fn create_image(
154 context: cl_context,
155 flags: cl_mem_flags,
156 image_format: *const cl_image_format,
157 image_desc: *const cl_image_desc,
158 host_ptr: *mut c_void,
159) -> Result<cl_mem, cl_int> {
160 let mut status: cl_int = CL_INVALID_VALUE;
161 let mem: cl_mem = cl_call!(clCreateImage(
162 context,
163 flags,
164 image_format,
165 image_desc,
166 host_ptr,
167 &raw mut status,
168 ));
169 if CL_SUCCESS == status {
170 Ok(mem)
171 } else {
172 Err(status)
173 }
174}
175
176/// Create an `OpenCL` pipe object for a context.
177/// Calls `clCreatePipe` to create an `OpenCL` pipe object.
178/// `CL_VERSION_2_0`
179///
180/// * `context` - a valid `OpenCL` context.
181/// * `flags` - a bit-field used to specify allocation and usage information
182/// about the image memory object being created, see:
183/// [Memory Flags](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#memory-flags-table).
184/// * `pipe_packet_size` - the size in bytes of a pipe packet.
185/// * `pipe_max_packets` -the maximum number of packets the pipe can hold.
186/// * `properties` - currently must be NULL.
187///
188/// returns a Result containing the new `OpenCL` pipe object
189/// or the error code from the `OpenCL` C API function.
190///
191/// # Safety
192///
193/// This function is unsafe because incorrect `flags` can cause undefined behaviour.
194#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
195#[inline]
196pub unsafe fn create_pipe(
197 context: cl_context,
198 flags: cl_mem_flags,
199 pipe_packet_size: cl_uint,
200 pipe_max_packets: cl_uint,
201 // properties: *const cl_pipe_properties,
202) -> Result<cl_mem, cl_int> {
203 let mut status: cl_int = CL_INVALID_VALUE;
204 let mem: cl_mem = cl_call!(clCreatePipe(
205 context,
206 flags,
207 pipe_packet_size,
208 pipe_max_packets,
209 ptr::null(),
210 &raw mut status,
211 ));
212 if CL_SUCCESS == status {
213 Ok(mem)
214 } else {
215 Err(status)
216 }
217}
218
219/// Create an `OpenCL` buffer object for a context.
220/// Calls `clCreateBufferWithProperties` to create an `OpenCL` buffer object.
221/// `CL_VERSION_3_0`
222///
223/// * `context` - a valid `OpenCL` context.
224/// * `properties` - an optional null terminated list of properties.
225/// * `flags` - a bit-field used to specify allocation and usage information
226/// about the image memory object being created, see:
227/// [Memory Flags](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#memory-flags-table).
228/// * `size` - the size in bytes of the buffer memory object to be allocated.
229/// * `host_ptr` - a pointer to the buffer data that may already be allocated
230/// by the application.
231///
232/// returns a Result containing the new `OpenCL` buffer object
233/// or the error code from the `OpenCL` C API function.
234///
235/// # Safety
236///
237/// This function is unsafe because incorrect `flags` can cause undefined behaviour.
238#[cfg(any(feature = "CL_VERSION_3_0", feature = "dynamic"))]
239#[inline]
240pub unsafe fn create_buffer_with_properties(
241 context: cl_context,
242 properties: *const cl_mem_properties,
243 flags: cl_mem_flags,
244 size: size_t,
245 host_ptr: *mut c_void,
246) -> Result<cl_mem, cl_int> {
247 let mut status: cl_int = CL_INVALID_VALUE;
248 let mem: cl_mem = cl_call!(clCreateBufferWithProperties(
249 context,
250 properties,
251 flags,
252 size,
253 host_ptr,
254 &raw mut status
255 ));
256 if CL_SUCCESS == status {
257 Ok(mem)
258 } else {
259 Err(status)
260 }
261}
262
263/// Create an `OpenCL` image object for a context.
264/// Calls `clCreateImage` to create an `OpenCL` image object.
265/// `CL_VERSION_3_0`
266///
267/// * `context` - a valid `OpenCL` context.
268/// * `properties` - an optional null terminated list of properties.
269/// * `flags` - a bit-field used to specify allocation and usage information
270/// about the image memory object being created, see:
271/// [Memory Flags](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#memory-flags-table).
272/// * `image_format` - a pointer to a structure that describes format properties
273/// of the image to be allocated.
274/// * `image_desc` - a pointer to a structure that describes type and dimensions
275/// of the image to be allocated.
276/// * `host_ptr` - a pointer to the image data that may already be allocated
277/// by the application.
278///
279/// returns a Result containing the new `OpenCL` image object
280/// or the error code from the `OpenCL` C API function.
281///
282/// # Safety
283///
284/// This function is unsafe because incorrect `flags` can cause undefined behaviour.
285#[inline]
286#[cfg(any(feature = "CL_VERSION_3_0", feature = "dynamic"))]
287pub unsafe fn create_image_with_properties(
288 context: cl_context,
289 properties: *const cl_mem_properties,
290 flags: cl_mem_flags,
291 image_format: *const cl_image_format,
292 image_desc: *const cl_image_desc,
293 host_ptr: *mut c_void,
294) -> Result<cl_mem, cl_int> {
295 let mut status: cl_int = CL_INVALID_VALUE;
296 let mem: cl_mem = cl_call!(clCreateImageWithProperties(
297 context,
298 properties,
299 flags,
300 image_format,
301 image_desc,
302 host_ptr,
303 &raw mut status,
304 ));
305 if CL_SUCCESS == status {
306 Ok(mem)
307 } else {
308 Err(status)
309 }
310}
311
312/// Retain an `OpenCL` memory object.
313/// Calls `clRetainMemObject` to increment the memory object reference count.
314///
315/// * `memobj` - the `OpenCL` memory object.
316///
317/// returns an empty Result or the error code from the `OpenCL` C API function.
318///
319/// # Safety
320///
321/// This function is unsafe because it changes the `OpenCL` object reference count.
322#[inline]
323pub unsafe fn retain_mem_object(memobj: cl_mem) -> Result<(), cl_int> {
324 let status: cl_int = cl_call!(clRetainMemObject(memobj));
325 if CL_SUCCESS == status {
326 Ok(())
327 } else {
328 Err(status)
329 }
330}
331
332/// Release an `OpenCL` memory object.
333/// Calls `clReleaseMemObject` to decrement the memory object reference count.
334///
335/// * `memobj` - the `OpenCL` memory object.
336///
337/// returns an empty Result or the error code from the `OpenCL` C API function.
338///
339/// # Safety
340///
341/// This function is unsafe because it changes the `OpenCL` object reference count.
342#[inline]
343pub unsafe fn release_mem_object(memobj: cl_mem) -> Result<(), cl_int> {
344 let status: cl_int = cl_call!(clReleaseMemObject(memobj));
345 if CL_SUCCESS == status {
346 Ok(())
347 } else {
348 Err(status)
349 }
350}
351
352fn count_supported_image_formats(
353 context: cl_context,
354 flags: cl_mem_flags,
355 image_type: cl_mem_object_type,
356) -> Result<cl_uint, cl_int> {
357 let mut count: cl_uint = 0;
358 let status: cl_int = unsafe {
359 cl_call!(clGetSupportedImageFormats(
360 context,
361 flags,
362 image_type,
363 0,
364 ptr::null_mut(),
365 &raw mut count
366 ))
367 };
368 if CL_SUCCESS == status {
369 Ok(count)
370 } else {
371 Err(status)
372 }
373}
374
375/// Get the list of image formats supported by an `OpenCL` implementation for a
376/// specified context, image type, and allocation information.
377///
378/// Calls `clGetSupportedImageFormats` to get the desired information about the program.
379///
380/// * `context` - a valid `OpenCL` context on which the image object(s) will be created.
381/// * `flags` - a bit-field used to specify allocation and usage information
382/// about the image memory object being created, see:
383/// [Memory Flags](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#memory-flags-table).
384/// * `image_type` - describes the image type.
385///
386/// returns a Result containing the desired information in an `InfoType` enum
387/// or the error code from the `OpenCL` C API function.
388#[inline]
389pub fn get_supported_image_formats(
390 context: cl_context,
391 flags: cl_mem_flags,
392 image_type: cl_mem_object_type,
393) -> Result<Vec<cl_image_format>, cl_int> {
394 let count: cl_uint = count_supported_image_formats(context, flags, image_type)?;
395 let mut image_formats: Vec<cl_image_format> = Vec::with_capacity(count as usize);
396 let status: cl_int = unsafe {
397 image_formats.set_len(count as usize);
398 cl_call!(clGetSupportedImageFormats(
399 context,
400 flags,
401 image_type,
402 count,
403 image_formats.as_mut_ptr(),
404 ptr::null_mut(),
405 ))
406 };
407 if CL_SUCCESS == status {
408 Ok(image_formats)
409 } else {
410 Err(status)
411 }
412}
413
414/// Get data about an `OpenCL` memory object.
415/// Calls `clGetMemObjectInfo` to get the desired data about the memory object.
416pub fn get_mem_object_data(memobj: cl_mem, param_name: cl_mem_info) -> Result<Vec<u8>, cl_int> {
417 api_info_size!(get_size, clGetMemObjectInfo);
418 let size = get_size(memobj, param_name)?;
419 api_info_vector!(get_vector, u8, clGetMemObjectInfo);
420 get_vector(memobj, param_name, size)
421}
422
423/// Get information common to all `OpenCL` memory objects (buffer and image objects).
424/// Calls `clGetMemObjectInfo` to get the desired information about the memory objects.
425///
426/// * `memobj` - the `OpenCL` memory objects.
427/// * `param_name` - the type of memory object information being queried, see:
428/// [Memory Object Info](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#mem-info-table).
429///
430/// returns a Result containing the desired information in an `InfoType` enum
431/// or the error code from the `OpenCL` C API function.
432pub fn get_mem_object_info(memobj: cl_mem, param_name: cl_mem_info) -> Result<InfoType, cl_int> {
433 match param_name {
434 CL_MEM_TYPE
435 | CL_MEM_MAP_COUNT
436 | CL_MEM_REFERENCE_COUNT
437 | CL_MEM_USES_SVM_POINTER // CL_VERSION_2_0
438 => {
439 api_info_value!(get_value, cl_uint, clGetMemObjectInfo);
440 Ok(InfoType::Uint(get_value(memobj, param_name)?))
441 }
442
443 CL_MEM_FLAGS => {
444 api_info_value!(get_value, cl_ulong, clGetMemObjectInfo);
445 Ok(InfoType::Ulong(get_value(memobj, param_name)?))
446 }
447
448 CL_MEM_SIZE | CL_MEM_OFFSET => {
449 api_info_value!(get_value, size_t, clGetMemObjectInfo);
450 Ok(InfoType::Size(get_value(memobj, param_name)?))
451 }
452
453 CL_MEM_HOST_PTR | CL_MEM_CONTEXT | CL_MEM_ASSOCIATED_MEMOBJECT => {
454 api_info_value!(get_value, intptr_t, clGetMemObjectInfo);
455 Ok(InfoType::Ptr(get_value(memobj, param_name)?))
456 }
457
458 CL_MEM_PROPERTIES // CL_VERSION_3_0
459 => {
460 api_info_size!(get_size, clGetMemObjectInfo);
461 api_info_vector!(get_vec, cl_ulong, clGetMemObjectInfo);
462 let size = get_size(memobj, param_name)?;
463 Ok(InfoType::VecUlong(get_vec(memobj, param_name, size)?))
464 }
465
466 _ => Ok(InfoType::VecUchar(get_mem_object_data(memobj, param_name)?))
467 }
468}
469
470/// Get data about an `OpenCL` image object.
471/// Calls `clGetImageInfo` to get the desired data about the image object.
472pub fn get_image_data(image: cl_mem, param_name: cl_image_info) -> Result<Vec<u8>, cl_int> {
473 api_info_size!(get_size, clGetImageInfo);
474 let size = get_size(image, param_name)?;
475 api_info_vector!(get_vector, u8, clGetImageInfo);
476 get_vector(image, param_name, size)
477}
478
479/// Get information specific to an `OpenCL` image object.
480/// Calls `clGetImageInfo` to get the desired information about the image object.
481///
482/// * `image` - the `OpenCL` image object.
483/// * `param_name` - the type of memory object information being queried, see:
484/// [Image Object Info](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#image-info-table).
485///
486/// returns a Result containing the desired information in an `InfoType` enum
487/// or the error code from the `OpenCL` C API function.
488pub fn get_image_info(image: cl_mem, param_name: cl_image_info) -> Result<InfoType, cl_int> {
489 match param_name {
490 CL_IMAGE_FORMAT => {
491 api_info_size!(get_size, clGetImageInfo);
492 api_info_vector!(get_vec, cl_image_format, clGetImageInfo);
493 let size = get_size(image, param_name)?;
494 Ok(InfoType::VecImageFormat(get_vec(image, param_name, size)?))
495 }
496
497 CL_IMAGE_ELEMENT_SIZE
498 | CL_IMAGE_ROW_PITCH
499 | CL_IMAGE_SLICE_PITCH
500 | CL_IMAGE_WIDTH
501 | CL_IMAGE_HEIGHT
502 | CL_IMAGE_DEPTH
503 | CL_IMAGE_ARRAY_SIZE => {
504 api_info_value!(get_value, size_t, clGetImageInfo);
505 Ok(InfoType::Size(get_value(image, param_name)?))
506 }
507
508 CL_IMAGE_BUFFER => {
509 api_info_value!(get_value, intptr_t, clGetImageInfo);
510 Ok(InfoType::Ptr(get_value(image, param_name)?))
511 }
512
513 CL_IMAGE_NUM_MIP_LEVELS | CL_IMAGE_NUM_SAMPLES => {
514 api_info_value!(get_value, cl_uint, clGetImageInfo);
515 Ok(InfoType::Uint(get_value(image, param_name)?))
516 }
517
518 _ => Ok(InfoType::VecUchar(get_image_data(image, param_name)?)),
519 }
520}
521
522/// Get data about an `OpenCL` pipe object.
523/// Calls `clGetPipeInfo` to get the desired data about the pipe object.
524#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
525pub fn get_pipe_data(pipe: cl_mem, param_name: cl_pipe_info) -> Result<Vec<u8>, cl_int> {
526 api_info_size!(get_size, clGetPipeInfo);
527 let size = get_size(pipe, param_name)?;
528 api_info_vector!(get_vector, u8, clGetPipeInfo);
529 get_vector(pipe, param_name, size)
530}
531
532/// Get information specific to an `OpenCL` pipe object.
533/// Calls `clGetPipeInfo` to get the desired information about the pipe object.
534/// `CL_VERSION_2_0`
535///
536/// * `pipe` - the `OpenCL` pipe object.
537/// * `param_name` - the type of pipe object information being queried, see:
538/// [Pipe Object Queries](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#pipe-info-table).
539///
540/// returns a Result containing the desired information in an `InfoType` enum
541/// or the error code from the `OpenCL` C API function.
542#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
543pub fn get_pipe_info(pipe: cl_mem, param_name: cl_pipe_info) -> Result<InfoType, cl_int> {
544 match param_name {
545 CL_PIPE_PACKET_SIZE | CL_PIPE_MAX_PACKETS => {
546 api_info_value!(get_value, cl_uint, clGetPipeInfo);
547 Ok(InfoType::Uint(get_value(pipe, param_name)?))
548 }
549 // CL_VERSION_3_0
550 CL_PIPE_PROPERTIES => {
551 api_info_size!(get_size, clGetPipeInfo);
552 api_info_vector!(get_vec, intptr_t, clGetPipeInfo);
553 let size = get_size(pipe, param_name)?;
554 Ok(InfoType::VecIntPtr(get_vec(pipe, param_name, size)?))
555 }
556
557 _ => Ok(InfoType::VecUchar(get_pipe_data(pipe, param_name)?)),
558 }
559}
560
561/// Register a callback function with an `OpenCL` memory object that is called when the
562/// memory object is destroyed.
563/// Calls `clSetMemObjectDestructorCallback`.
564///
565/// * `memobj` - the `OpenCL` memory object.
566/// * `pfn_notify` - callback function to be registered by the application.
567/// * `user_data` - passed as the `user_data` argument when `pfn_notify` is called.
568///
569/// returns an empty Result or the error code from the `OpenCL` C API function.
570///
571/// # Safety
572///
573/// This function is unsafe because `user_data` must be valid.
574#[inline]
575pub unsafe fn set_mem_object_destructor_callback(
576 memobj: cl_mem,
577 pfn_notify: extern "C" fn(cl_mem, *mut c_void),
578 user_data: *mut c_void,
579) -> Result<(), cl_int> {
580 let status: cl_int = cl_call!(clSetMemObjectDestructorCallback(
581 memobj,
582 Some(pfn_notify),
583 user_data
584 ));
585 if CL_SUCCESS == status {
586 Ok(())
587 } else {
588 Err(status)
589 }
590}
591
592/// Allocate a shared virtual memory (SVM) buffer that can be shared by the
593/// host and all devices in an `OpenCL` context.
594/// Calls `clSVMAlloc`.
595/// `CL_VERSION_2_0`
596///
597/// * `context` - a valid `OpenCL` context.
598/// * `flags` - a bit-field used to specify allocation and usage information, see:
599/// [SVM Memory Flags](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#svm-flags-table).
600/// * `size` - the size in bytes of the SVM buffer to be allocated.
601/// * `alignment` - the minimum alignment in bytes that is required for the
602/// newly created buffers memory region.
603///
604/// returns Result containing the address of the SVM buffer
605/// or the error code: `CL_INVALID_VALUE` if the address is NULL.
606///
607/// # Safety
608///
609/// This function is unsafe because `flags` must be valid.
610#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
611#[inline]
612pub unsafe fn svm_alloc(
613 context: cl_context,
614 flags: cl_svm_mem_flags,
615 size: size_t,
616 alignment: cl_uint,
617) -> Result<*mut c_void, cl_int> {
618 let ptr = cl_call!(clSVMAlloc(context, flags, size, alignment));
619 if ptr.is_null() {
620 Err(CL_INVALID_VALUE)
621 } else {
622 Ok(ptr)
623 }
624}
625
626/// Free a shared virtual memory (SVM) buffer allocated using `clSVMAlloc`.
627/// Calls `clSVMFree`.
628/// `CL_VERSION_2_0`
629///
630/// * `context` - the valid `OpenCL` context used to create the SVM buffer.
631/// * `svm_pointer` - the value returned by a call to clSVMAlloc.
632///
633/// # Safety
634///
635/// This function is unsafe because `svm_pointer` is no longer valid after it is called.
636#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
637#[inline]
638pub unsafe fn svm_free(context: cl_context, svm_pointer: *mut c_void) -> Result<(), cl_int> {
639 cl_call!(clSVMFree(context, svm_pointer));
640 Ok(())
641}