#![allow(non_camel_case_types, deprecated)]
#![allow(clippy::not_unsafe_ptr_arg_deref, clippy::missing_safety_doc)]
pub use opencl_sys::{
cl_GLenum, cl_GLint, cl_GLsync, cl_GLuint, cl_command_queue, cl_context, cl_context_properties,
cl_event, cl_gl_context_info, cl_gl_object_type, cl_gl_platform_info, cl_gl_texture_info,
cl_int, cl_mem, cl_mem_flags, cl_uint, CL_CGL_SHAREGROUP_KHR,
CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR,
CL_DEVICES_FOR_GL_CONTEXT_KHR, CL_EGL_DISPLAY_KHR, CL_GLX_DISPLAY_KHR, CL_GL_CONTEXT_KHR,
CL_GL_MIPMAP_LEVEL, CL_GL_NUM_SAMPLES, CL_GL_OBJECT_BUFFER, CL_GL_OBJECT_RENDERBUFFER,
CL_GL_OBJECT_TEXTURE1D, CL_GL_OBJECT_TEXTURE1D_ARRAY, CL_GL_OBJECT_TEXTURE2D,
CL_GL_OBJECT_TEXTURE2D_ARRAY, CL_GL_OBJECT_TEXTURE3D, CL_GL_OBJECT_TEXTURE_BUFFER,
CL_GL_TEXTURE_TARGET, CL_INVALID_VALUE, CL_KHR_GL_SHARING, CL_SUCCESS, CL_WGL_HDC_KHR,
};
#[allow(unused_imports)]
use opencl_sys::{
clCreateEventFromGLsyncKHR, clCreateFromGLBuffer, clCreateFromGLRenderbuffer,
clCreateFromGLTexture, clCreateFromGLTexture2D, clCreateFromGLTexture3D,
clEnqueueAcquireGLObjects, clEnqueueReleaseGLObjects, clGetGLContextInfoKHR, clGetGLObjectInfo,
clGetGLTextureInfo,
};
use super::info_type::InfoType;
use super::{api_info_size, api_info_value, api_info_vector};
#[allow(unused_imports)]
use libc::{c_void, intptr_t, size_t};
use std::mem;
use std::ptr;
#[inline]
pub unsafe fn create_from_gl_buffer(
context: cl_context,
flags: cl_mem_flags,
bufobj: cl_GLuint,
) -> Result<cl_mem, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let mem = clCreateFromGLBuffer(context, flags, bufobj, &mut status);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(mem)
}
}
#[inline]
pub unsafe fn create_from_gl_texture(
context: cl_context,
flags: cl_mem_flags,
texture_target: cl_GLenum,
miplevel: cl_GLint,
texture: cl_GLuint,
) -> Result<cl_mem, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let mem = clCreateFromGLTexture(
context,
flags,
texture_target,
miplevel,
texture,
&mut status,
);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(mem)
}
}
#[inline]
pub unsafe fn create_from_gl_render_buffer(
context: cl_context,
flags: cl_mem_flags,
renderbuffer: cl_GLuint,
) -> Result<cl_mem, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let mem = clCreateFromGLRenderbuffer(context, flags, renderbuffer, &mut status);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(mem)
}
}
#[inline]
pub fn get_gl_object_info(memobj: cl_mem) -> Result<(cl_GLuint, cl_GLuint), cl_int> {
let mut object_type: cl_uint = CL_GL_OBJECT_BUFFER;
let mut object_name: cl_uint = 0;
let status = unsafe { clGetGLObjectInfo(memobj, &mut object_type, &mut object_name) };
if CL_SUCCESS != status {
Err(status)
} else {
Ok((object_type, object_name))
}
}
pub fn get_gl_texture_data(
memobj: cl_mem,
param_name: cl_gl_texture_info,
) -> Result<Vec<u8>, cl_int> {
api_info_size!(get_size, clGetGLTextureInfo);
let size = get_size(memobj, param_name)?;
api_info_vector!(get_vector, u8, clGetGLTextureInfo);
get_vector(memobj, param_name, size)
}
pub fn get_gl_texture_info(
memobj: cl_mem,
param_name: cl_gl_texture_info,
) -> Result<InfoType, cl_int> {
match param_name {
CL_GL_TEXTURE_TARGET => {
api_info_value!(get_value, cl_GLenum, clGetGLTextureInfo);
Ok(InfoType::Uint(get_value(memobj, param_name)?))
}
CL_GL_MIPMAP_LEVEL | CL_GL_NUM_SAMPLES => {
api_info_value!(get_value, cl_GLint, clGetGLTextureInfo);
Ok(InfoType::Int(get_value(memobj, param_name)?))
}
_ => Ok(InfoType::VecUchar(get_gl_texture_data(memobj, param_name)?)),
}
}
#[inline]
pub unsafe fn enqueue_acquire_gl_objects(
command_queue: cl_command_queue,
num_objects: cl_uint,
mem_objects: *const cl_mem,
num_events_in_wait_list: cl_uint,
event_wait_list: *const cl_event,
) -> Result<cl_event, cl_int> {
let mut event: cl_event = ptr::null_mut();
let status: cl_int = clEnqueueAcquireGLObjects(
command_queue,
num_objects,
mem_objects,
num_events_in_wait_list,
event_wait_list,
&mut event,
);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(event)
}
}
#[inline]
pub unsafe fn enqueue_release_gl_objects(
command_queue: cl_command_queue,
num_objects: cl_uint,
mem_objects: *const cl_mem,
num_events_in_wait_list: cl_uint,
event_wait_list: *const cl_event,
) -> Result<cl_event, cl_int> {
let mut event: cl_event = ptr::null_mut();
let status: cl_int = clEnqueueReleaseGLObjects(
command_queue,
num_objects,
mem_objects,
num_events_in_wait_list,
event_wait_list,
&mut event,
);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(event)
}
}
#[cfg_attr(
any(
feature = "CL_VERSION_1_2",
feature = "CL_VERSION_2_0",
feature = "CL_VERSION_2_1",
feature = "CL_VERSION_2_2",
feature = "CL_VERSION_3_0"
),
deprecated(
since = "0.1.0",
note = "From CL_VERSION_1_2 use create_from_gl_texture"
)
)]
#[inline]
pub unsafe fn create_from_gl_texture_2d(
context: cl_context,
flags: cl_mem_flags,
texture_target: cl_GLenum,
miplevel: cl_GLint,
texture: cl_GLuint,
) -> Result<cl_mem, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let mem = clCreateFromGLTexture2D(
context,
flags,
texture_target,
miplevel,
texture,
&mut status,
);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(mem)
}
}
#[cfg_attr(
any(
feature = "CL_VERSION_1_2",
feature = "CL_VERSION_2_0",
feature = "CL_VERSION_2_1",
feature = "CL_VERSION_2_2",
feature = "CL_VERSION_3_0"
),
deprecated(
since = "0.1.0",
note = "From CL_VERSION_1_2 use create_from_gl_texture"
)
)]
#[inline]
pub unsafe fn create_from_gl_texture_3d(
context: cl_context,
flags: cl_mem_flags,
texture_target: cl_GLenum,
miplevel: cl_GLint,
texture: cl_GLuint,
) -> Result<cl_mem, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let mem = clCreateFromGLTexture3D(
context,
flags,
texture_target,
miplevel,
texture,
&mut status,
);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(mem)
}
}
#[cfg(feature = "cl_khr_gl_sharing")]
pub fn get_gl_context_info_khr(
properties: *mut cl_context_properties,
param_name: cl_gl_context_info,
) -> Result<InfoType, cl_int> {
match param_name {
CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR => {
let mut data: intptr_t = 0;
let data_ptr: *mut intptr_t = &mut data;
let status = unsafe {
clGetGLContextInfoKHR(
properties,
param_name,
mem::size_of::<intptr_t>(),
data_ptr as *mut c_void,
ptr::null_mut(),
)
};
if CL_SUCCESS != status {
Err(status)
} else {
Ok(InfoType::Ptr(data))
}
}
CL_DEVICES_FOR_GL_CONTEXT_KHR => {
let mut size: size_t = 0;
let status = unsafe {
clGetGLContextInfoKHR(properties, param_name, 0, ptr::null_mut(), &mut size)
};
if CL_SUCCESS != status {
Err(status)
} else if 0 < size {
let count = size / mem::size_of::<intptr_t>();
let mut data: Vec<intptr_t> = Vec::with_capacity(count);
let status = unsafe {
clGetGLContextInfoKHR(
properties,
param_name,
size,
data.as_mut_ptr() as *mut c_void,
ptr::null_mut(),
)
};
if CL_SUCCESS != status {
Err(status)
} else {
Ok(InfoType::VecIntPtr(data))
}
} else {
Ok(InfoType::VecIntPtr(Vec::default()))
}
}
_ => {
let mut size: size_t = 0;
let status = unsafe {
clGetGLContextInfoKHR(properties, param_name, 0, ptr::null_mut(), &mut size)
};
if CL_SUCCESS != status {
Err(status)
} else if 0 < size {
let mut data: Vec<u8> = Vec::with_capacity(size);
let status = unsafe {
clGetGLContextInfoKHR(
properties,
param_name,
size,
data.as_mut_ptr() as *mut c_void,
ptr::null_mut(),
)
};
if CL_SUCCESS != status {
Err(status)
} else {
Ok(InfoType::VecUchar(data))
}
} else {
Ok(InfoType::VecUchar(Vec::default()))
}
}
}
}
#[cfg(feature = "cl_khr_gl_event")]
#[inline]
pub fn create_event_from_gl_sync_khr(
context: cl_context,
sync: cl_GLsync,
) -> Result<cl_event, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let event: cl_event = unsafe { clCreateEventFromGLsyncKHR(context, sync, &mut status) };
if CL_SUCCESS != status {
Err(status)
} else {
Ok(event)
}
}