#![allow(non_camel_case_types)]
#![allow(clippy::not_unsafe_ptr_arg_deref)]
pub use opencl_sys::{
cl_buffer_create_type, cl_buffer_region, cl_context, cl_image_desc, cl_image_format,
cl_image_info, cl_int, cl_mem, cl_mem_flags, cl_mem_info, cl_mem_object_type,
cl_mem_properties, cl_pipe_info, cl_svm_mem_flags, cl_uint, cl_ulong, CL_RGBx, CL_RGx, CL_Rx,
CL_sRGB, CL_sRGBA, CL_sRGBx, CL_A, CL_ABGR, CL_ADDRESS_CLAMP, CL_ADDRESS_CLAMP_TO_EDGE,
CL_ADDRESS_MIRRORED_REPEAT, CL_ADDRESS_NONE, CL_ADDRESS_REPEAT, CL_ARGB, CL_BGRA,
CL_BUFFER_CREATE_TYPE_REGION, CL_DEPTH, CL_DEPTH_STENCIL, CL_FALSE, CL_FILTER_LINEAR,
CL_FILTER_NEAREST, CL_FLOAT, CL_HALF_FLOAT, CL_IMAGE_ARRAY_SIZE, CL_IMAGE_BUFFER,
CL_IMAGE_DEPTH, CL_IMAGE_ELEMENT_SIZE, CL_IMAGE_FORMAT, CL_IMAGE_HEIGHT,
CL_IMAGE_NUM_MIP_LEVELS, CL_IMAGE_NUM_SAMPLES, CL_IMAGE_ROW_PITCH, CL_IMAGE_SLICE_PITCH,
CL_IMAGE_WIDTH, CL_INTENSITY, CL_INVALID_VALUE, CL_LUMINANCE, CL_MAP_READ, CL_MAP_WRITE,
CL_MAP_WRITE_INVALIDATE_REGION, CL_MEM_ALLOC_HOST_PTR, CL_MEM_ASSOCIATED_MEMOBJECT,
CL_MEM_CONTEXT, CL_MEM_COPY_HOST_PTR, CL_MEM_FLAGS, CL_MEM_HOST_NO_ACCESS, CL_MEM_HOST_PTR,
CL_MEM_HOST_READ_ONLY, CL_MEM_HOST_WRITE_ONLY, CL_MEM_KERNEL_READ_AND_WRITE, CL_MEM_MAP_COUNT,
CL_MEM_OBJECT_BUFFER, CL_MEM_OBJECT_IMAGE1D, CL_MEM_OBJECT_IMAGE1D_ARRAY,
CL_MEM_OBJECT_IMAGE1D_BUFFER, CL_MEM_OBJECT_IMAGE2D, CL_MEM_OBJECT_IMAGE2D_ARRAY,
CL_MEM_OBJECT_IMAGE3D, CL_MEM_OBJECT_PIPE, CL_MEM_OFFSET, CL_MEM_PROPERTIES, CL_MEM_READ_ONLY,
CL_MEM_READ_WRITE, CL_MEM_REFERENCE_COUNT, CL_MEM_SIZE, CL_MEM_SVM_ATOMICS,
CL_MEM_SVM_FINE_GRAIN_BUFFER, CL_MEM_TYPE, CL_MEM_USES_SVM_POINTER, CL_MEM_USE_HOST_PTR,
CL_MEM_WRITE_ONLY, CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED, CL_MIGRATE_MEM_OBJECT_HOST,
CL_PIPE_MAX_PACKETS, CL_PIPE_PACKET_SIZE, CL_PIPE_PROPERTIES, CL_R, CL_RA, CL_RG, CL_RGB,
CL_RGBA, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_SIGNED_INT8, CL_SNORM_INT16, CL_SNORM_INT8,
CL_SUCCESS, CL_TRUE, CL_UNORM_INT16, CL_UNORM_INT24, CL_UNORM_INT8, CL_UNORM_INT_101010,
CL_UNORM_INT_101010_2, CL_UNORM_SHORT_555, CL_UNORM_SHORT_565, CL_UNSIGNED_INT16,
CL_UNSIGNED_INT32, CL_UNSIGNED_INT8,
};
use opencl_sys::{
clCreateBuffer, clCreateImage, clCreateSubBuffer, clGetImageInfo, clGetMemObjectInfo,
clGetSupportedImageFormats, clReleaseMemObject, clRetainMemObject,
clSetMemObjectDestructorCallback,
};
#[cfg(feature = "CL_VERSION_2_0")]
use opencl_sys::{clCreatePipe, clGetPipeInfo, clSVMAlloc, clSVMFree};
#[cfg(feature = "CL_VERSION_3_0")]
use opencl_sys::{clCreateBufferWithProperties, clCreateImageWithProperties};
use super::info_type::InfoType;
use super::{api_info_size, api_info_value, api_info_vector};
use libc::{c_void, intptr_t, size_t};
use std::mem;
use std::ptr;
#[inline]
pub unsafe fn create_buffer(
context: cl_context,
flags: cl_mem_flags,
size: size_t,
host_ptr: *mut c_void,
) -> Result<cl_mem, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let mem: cl_mem = clCreateBuffer(context, flags, size, host_ptr, &mut status);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(mem)
}
}
#[inline]
pub unsafe fn create_sub_buffer(
buffer: cl_mem,
flags: cl_mem_flags,
buffer_create_type: cl_buffer_create_type,
buffer_create_info: *const c_void,
) -> Result<cl_mem, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let mem: cl_mem = clCreateSubBuffer(
buffer,
flags,
buffer_create_type,
buffer_create_info,
&mut status,
);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(mem)
}
}
#[cfg(feature = "CL_VERSION_1_2")]
#[inline]
pub unsafe fn create_image(
context: cl_context,
flags: cl_mem_flags,
image_format: *const cl_image_format,
image_desc: *const cl_image_desc,
host_ptr: *mut c_void,
) -> Result<cl_mem, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let mem: cl_mem = clCreateImage(
context,
flags,
image_format,
image_desc,
host_ptr,
&mut status,
);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(mem)
}
}
#[cfg(feature = "CL_VERSION_2_0")]
#[inline]
pub unsafe fn create_pipe(
context: cl_context,
flags: cl_mem_flags,
pipe_packet_size: cl_uint,
pipe_max_packets: cl_uint,
) -> Result<cl_mem, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let mem: cl_mem = clCreatePipe(
context,
flags,
pipe_packet_size,
pipe_max_packets,
ptr::null(),
&mut status,
);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(mem)
}
}
#[cfg(feature = "CL_VERSION_3_0")]
#[inline]
pub unsafe fn create_buffer_with_properties(
context: cl_context,
properties: *const cl_mem_properties,
flags: cl_mem_flags,
size: size_t,
host_ptr: *mut c_void,
) -> Result<cl_mem, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let mem: cl_mem =
clCreateBufferWithProperties(context, properties, flags, size, host_ptr, &mut status);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(mem)
}
}
#[inline]
#[cfg(feature = "CL_VERSION_3_0")]
pub unsafe fn create_image_with_properties(
context: cl_context,
properties: *const cl_mem_properties,
flags: cl_mem_flags,
image_format: *const cl_image_format,
image_desc: *const cl_image_desc,
host_ptr: *mut c_void,
) -> Result<cl_mem, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let mem: cl_mem = clCreateImageWithProperties(
context,
properties,
flags,
image_format,
image_desc,
host_ptr,
&mut status,
);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(mem)
}
}
#[inline]
pub unsafe fn retain_mem_object(memobj: cl_mem) -> Result<(), cl_int> {
let status: cl_int = clRetainMemObject(memobj);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(())
}
}
#[inline]
pub unsafe fn release_mem_object(memobj: cl_mem) -> Result<(), cl_int> {
let status: cl_int = clReleaseMemObject(memobj);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(())
}
}
fn count_supported_image_formats(
context: cl_context,
flags: cl_mem_flags,
image_type: cl_mem_object_type,
) -> Result<cl_uint, cl_int> {
let mut count: cl_uint = 0;
let status: cl_int = unsafe {
clGetSupportedImageFormats(context, flags, image_type, 0, ptr::null_mut(), &mut count)
};
if CL_SUCCESS != status {
Err(status)
} else {
Ok(count)
}
}
#[inline]
pub fn get_supported_image_formats(
context: cl_context,
flags: cl_mem_flags,
image_type: cl_mem_object_type,
) -> Result<Vec<cl_image_format>, cl_int> {
let count: cl_uint = count_supported_image_formats(context, flags, image_type)?;
let mut image_formats: Vec<cl_image_format> = Vec::with_capacity(count as usize);
let status: cl_int = unsafe {
image_formats.set_len(count as usize);
clGetSupportedImageFormats(
context,
flags,
image_type,
count,
image_formats.as_mut_ptr() as *mut cl_image_format,
ptr::null_mut(),
)
};
if CL_SUCCESS != status {
Err(status)
} else {
Ok(image_formats)
}
}
pub fn get_mem_object_data(memobj: cl_mem, param_name: cl_mem_info) -> Result<Vec<u8>, cl_int> {
api_info_size!(get_size, clGetMemObjectInfo);
let size = get_size(memobj, param_name)?;
api_info_vector!(get_vector, u8, clGetMemObjectInfo);
get_vector(memobj, param_name, size)
}
pub fn get_mem_object_info(memobj: cl_mem, param_name: cl_mem_info) -> Result<InfoType, cl_int> {
match param_name {
CL_MEM_TYPE
| CL_MEM_MAP_COUNT
| CL_MEM_REFERENCE_COUNT
| CL_MEM_USES_SVM_POINTER => {
api_info_value!(get_value, cl_uint, clGetMemObjectInfo);
Ok(InfoType::Uint(get_value(memobj, param_name)?))
}
CL_MEM_FLAGS => {
api_info_value!(get_value, cl_ulong, clGetMemObjectInfo);
Ok(InfoType::Ulong(get_value(memobj, param_name)?))
}
CL_MEM_SIZE | CL_MEM_OFFSET => {
api_info_value!(get_value, size_t, clGetMemObjectInfo);
Ok(InfoType::Size(get_value(memobj, param_name)?))
}
CL_MEM_HOST_PTR | CL_MEM_CONTEXT | CL_MEM_ASSOCIATED_MEMOBJECT => {
api_info_value!(get_value, intptr_t, clGetMemObjectInfo);
Ok(InfoType::Ptr(get_value(memobj, param_name)?))
}
CL_MEM_PROPERTIES => {
api_info_size!(get_size, clGetMemObjectInfo);
api_info_vector!(get_vec, cl_ulong, clGetMemObjectInfo);
let size = get_size(memobj, param_name)?;
Ok(InfoType::VecUlong(get_vec(memobj, param_name, size)?))
}
_ => Ok(InfoType::VecUchar(get_mem_object_data(memobj, param_name)?))
}
}
pub fn get_image_data(image: cl_mem, param_name: cl_image_info) -> Result<Vec<u8>, cl_int> {
api_info_size!(get_size, clGetImageInfo);
let size = get_size(image, param_name)?;
api_info_vector!(get_vector, u8, clGetImageInfo);
get_vector(image, param_name, size)
}
pub fn get_image_info(image: cl_mem, param_name: cl_image_info) -> Result<InfoType, cl_int> {
match param_name {
CL_IMAGE_FORMAT => {
api_info_size!(get_size, clGetImageInfo);
api_info_vector!(get_vec, cl_image_format, clGetImageInfo);
let size = get_size(image, param_name)?;
Ok(InfoType::VecImageFormat(get_vec(image, param_name, size)?))
}
CL_IMAGE_ELEMENT_SIZE
| CL_IMAGE_ROW_PITCH
| CL_IMAGE_SLICE_PITCH
| CL_IMAGE_WIDTH
| CL_IMAGE_HEIGHT
| CL_IMAGE_DEPTH
| CL_IMAGE_ARRAY_SIZE => {
api_info_value!(get_value, size_t, clGetImageInfo);
Ok(InfoType::Size(get_value(image, param_name)?))
}
CL_IMAGE_BUFFER => {
api_info_value!(get_value, intptr_t, clGetImageInfo);
Ok(InfoType::Ptr(get_value(image, param_name)?))
}
CL_IMAGE_NUM_MIP_LEVELS | CL_IMAGE_NUM_SAMPLES => {
api_info_value!(get_value, cl_uint, clGetImageInfo);
Ok(InfoType::Uint(get_value(image, param_name)?))
}
_ => Ok(InfoType::VecUchar(get_image_data(image, param_name)?)),
}
}
#[cfg(feature = "CL_VERSION_2_0")]
pub fn get_pipe_data(pipe: cl_mem, param_name: cl_pipe_info) -> Result<Vec<u8>, cl_int> {
api_info_size!(get_size, clGetPipeInfo);
let size = get_size(pipe, param_name)?;
api_info_vector!(get_vector, u8, clGetPipeInfo);
get_vector(pipe, param_name, size)
}
#[cfg(feature = "CL_VERSION_2_0")]
pub fn get_pipe_info(pipe: cl_mem, param_name: cl_pipe_info) -> Result<InfoType, cl_int> {
match param_name {
CL_PIPE_PACKET_SIZE | CL_PIPE_MAX_PACKETS => {
api_info_value!(get_value, cl_uint, clGetPipeInfo);
Ok(InfoType::Uint(get_value(pipe, param_name)?))
}
CL_PIPE_PROPERTIES => {
api_info_size!(get_size, clGetPipeInfo);
api_info_vector!(get_vec, intptr_t, clGetPipeInfo);
let size = get_size(pipe, param_name)?;
Ok(InfoType::VecIntPtr(get_vec(pipe, param_name, size)?))
}
_ => Ok(InfoType::VecUchar(get_pipe_data(pipe, param_name)?)),
}
}
#[inline]
pub unsafe fn set_mem_object_destructor_callback(
memobj: cl_mem,
pfn_notify: extern "C" fn(cl_mem, *mut c_void),
user_data: *mut c_void,
) -> Result<(), cl_int> {
let status: cl_int = clSetMemObjectDestructorCallback(memobj, Some(pfn_notify), user_data);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(())
}
}
#[cfg(feature = "CL_VERSION_2_0")]
#[inline]
pub unsafe fn svm_alloc(
context: cl_context,
flags: cl_svm_mem_flags,
size: size_t,
alignment: cl_uint,
) -> Result<*mut c_void, cl_int> {
let ptr = clSVMAlloc(context, flags, size, alignment);
if ptr.is_null() {
Err(CL_INVALID_VALUE)
} else {
Ok(ptr)
}
}
#[cfg(feature = "CL_VERSION_2_0")]
#[inline]
pub unsafe fn svm_free(context: cl_context, svm_pointer: *mut c_void) {
clSVMFree(context, svm_pointer);
}