diff --git a/src/gallium/frontends/rusticl/api/context.rs b/src/gallium/frontends/rusticl/api/context.rs index 94af6ff4b6a..7c95657a227 100644 --- a/src/gallium/frontends/rusticl/api/context.rs +++ b/src/gallium/frontends/rusticl/api/context.rs @@ -6,6 +6,7 @@ use crate::api::icd::*; use crate::api::platform::*; use crate::api::types::*; use crate::api::util::*; +use crate::cl_closure; use crate::core::context::*; use self::mesa_rust_util::properties::Properties; @@ -115,3 +116,22 @@ pub fn create_context_from_type( user_data, ) } + +pub fn set_context_destructor_callback( + context: cl_context, + pfn_notify: ::std::option::Option, + user_data: *mut ::std::os::raw::c_void, +) -> CLResult<()> { + let c = context.get_ref()?; + + // CL_INVALID_VALUE if pfn_notify is NULL. + if pfn_notify.is_none() { + return Err(CL_INVALID_VALUE); + } + + c.dtors + .lock() + .unwrap() + .push(cl_closure!(|c| pfn_notify(c, user_data))); + Ok(()) +} diff --git a/src/gallium/frontends/rusticl/api/icd.rs b/src/gallium/frontends/rusticl/api/icd.rs index 0cd69f26c00..f1395ba93af 100644 --- a/src/gallium/frontends/rusticl/api/icd.rs +++ b/src/gallium/frontends/rusticl/api/icd.rs @@ -170,7 +170,7 @@ pub static DISPATCH: cl_icd_dispatch = cl_icd_dispatch { clSetProgramSpecializationConstant: None, clCreateBufferWithProperties: None, clCreateImageWithProperties: None, - clSetContextDestructorCallback: None, + clSetContextDestructorCallback: Some(cl_set_context_destructor_callback), }; pub type CLError = cl_int; @@ -1503,6 +1503,16 @@ extern "C" fn cl_create_command_queue_with_properties( match_obj!(create_command_queue(context, device, 0), errcode_ret) } +extern "C" fn cl_set_context_destructor_callback( + context: cl_context, + pfn_notify: ::std::option::Option, + user_data: *mut ::std::os::raw::c_void, +) -> cl_int { + match_err!(set_context_destructor_callback( + context, pfn_notify, user_data + )) +} + // cl_khr_icd extern "C" fn cl_icd_get_platform_ids_khr( num_entries: cl_uint, diff --git a/src/gallium/frontends/rusticl/api/types.rs b/src/gallium/frontends/rusticl/api/types.rs index 5b0391c661a..1dcc1755a7c 100644 --- a/src/gallium/frontends/rusticl/api/types.rs +++ b/src/gallium/frontends/rusticl/api/types.rs @@ -33,6 +33,13 @@ cl_callback!( } ); +cl_callback!( + DeleteContextCB { + context: cl_context, + user_data: *mut ::std::os::raw::c_void, + } +); + cl_callback!( EventCB { event: cl_event, diff --git a/src/gallium/frontends/rusticl/core/context.rs b/src/gallium/frontends/rusticl/core/context.rs index 74fc33a0d80..ca939d6296c 100644 --- a/src/gallium/frontends/rusticl/core/context.rs +++ b/src/gallium/frontends/rusticl/core/context.rs @@ -12,11 +12,13 @@ use std::collections::HashMap; use std::convert::TryInto; use std::os::raw::c_void; use std::sync::Arc; +use std::sync::Mutex; pub struct Context { pub base: CLObjectBase, pub devs: Vec>, pub properties: Vec, + pub dtors: Mutex>>, } impl_cl_type_trait!(cl_context, Context, CL_INVALID_CONTEXT); @@ -27,6 +29,7 @@ impl Context { base: CLObjectBase::new(), devs: devs, properties: properties, + dtors: Mutex::new(Vec::new()), }) } @@ -60,3 +63,15 @@ impl Context { Ok(res) } } + +impl Drop for Context { + fn drop(&mut self) { + let cl = cl_context::from_ptr(self); + self.dtors + .lock() + .unwrap() + .iter() + .rev() + .for_each(|cb| cb(cl)); + } +}