diff --git a/src/gallium/frontends/rusticl/api/context.rs b/src/gallium/frontends/rusticl/api/context.rs index 7c95657a227..b3fa9d691e9 100644 --- a/src/gallium/frontends/rusticl/api/context.rs +++ b/src/gallium/frontends/rusticl/api/context.rs @@ -33,7 +33,7 @@ impl CLInfo for cl_context { ) } CL_CONTEXT_NUM_DEVICES => cl_prop::(ctx.devs.len() as u32), - CL_CONTEXT_PROPERTIES => cl_prop::<&Vec>(&ctx.properties), + CL_CONTEXT_PROPERTIES => cl_prop::<&Properties>(&ctx.properties), CL_CONTEXT_REFERENCE_COUNT => cl_prop::(self.refcnt()?), // CL_INVALID_VALUE if param_name is not one of the supported values _ => return Err(CL_INVALID_VALUE), @@ -62,7 +62,7 @@ pub fn create_context( // CL_INVALID_PROPERTY [...] if the same property name is specified more than once. let props = Properties::from_ptr(properties).ok_or(CL_INVALID_PROPERTY)?; - for p in props.props { + for p in &props.props { match p.0 as u32 { // CL_INVALID_PLATFORM [...] if platform value specified in properties is not a valid platform. CL_CONTEXT_PLATFORM => { @@ -81,10 +81,7 @@ pub fn create_context( HashSet::from_iter(unsafe { slice::from_raw_parts(devices, num_devices as usize) }.iter()); let devs: Result<_, _> = set.into_iter().map(cl_device_id::get_arc).collect(); - Ok(cl_context::from_arc(Context::new( - devs?, - Properties::from_ptr_raw(properties), - ))) + Ok(cl_context::from_arc(Context::new(devs?, props))) } pub fn create_context_from_type( diff --git a/src/gallium/frontends/rusticl/api/icd.rs b/src/gallium/frontends/rusticl/api/icd.rs index 45a421103ed..dec64d71354 100644 --- a/src/gallium/frontends/rusticl/api/icd.rs +++ b/src/gallium/frontends/rusticl/api/icd.rs @@ -155,7 +155,7 @@ pub static DISPATCH: cl_icd_dispatch = cl_icd_dispatch { clEnqueueSVMMemFill: Some(cl_enqueue_svm_mem_fill), clEnqueueSVMMap: Some(cl_enqueue_svm_map), clEnqueueSVMUnmap: Some(cl_enqueue_svm_unmap), - clCreateSamplerWithProperties: None, + clCreateSamplerWithProperties: Some(cl_create_sampler_with_properties), clSetKernelArgSVMPointer: Some(cl_set_kernel_arg_svm_pointer), clSetKernelExecInfo: Some(cl_set_kernel_exec_info), clGetKernelSubGroupInfoKHR: Some(cl_get_kernel_sub_group_info), @@ -1693,6 +1693,17 @@ extern "C" fn cl_enqueue_svm_unmap( CL_INVALID_OPERATION } +extern "C" fn cl_create_sampler_with_properties( + context: cl_context, + sampler_properties: *const cl_sampler_properties, + errcode_ret: *mut cl_int, +) -> cl_sampler { + match_obj!( + create_sampler_with_properties(context, sampler_properties), + errcode_ret + ) +} + extern "C" fn cl_set_kernel_arg_svm_pointer( _kernel: cl_kernel, _arg_index: cl_uint, diff --git a/src/gallium/frontends/rusticl/api/memory.rs b/src/gallium/frontends/rusticl/api/memory.rs index b81073cc984..1de96f22829 100644 --- a/src/gallium/frontends/rusticl/api/memory.rs +++ b/src/gallium/frontends/rusticl/api/memory.rs @@ -840,17 +840,21 @@ impl CLInfo for cl_sampler { CL_SAMPLER_FILTER_MODE => cl_prop::(sampler.filter_mode), CL_SAMPLER_NORMALIZED_COORDS => cl_prop::(sampler.normalized_coords), CL_SAMPLER_REFERENCE_COUNT => cl_prop::(self.refcnt()?), + CL_SAMPLER_PROPERTIES => { + cl_prop::<&Option>>(&sampler.props) + } // CL_INVALID_VALUE if param_name is not one of the supported values _ => return Err(CL_INVALID_VALUE), }) } } -pub fn create_sampler( +fn create_sampler_impl( context: cl_context, normalized_coords: cl_bool, addressing_mode: cl_addressing_mode, filter_mode: cl_filter_mode, + props: Option>, ) -> CLResult { let c = context.get_arc()?; @@ -871,10 +875,62 @@ pub fn create_sampler( check_cl_bool(normalized_coords).ok_or(CL_INVALID_VALUE)?, addressing_mode, filter_mode, + props, ); Ok(cl_sampler::from_arc(sampler)) } +pub fn create_sampler( + context: cl_context, + normalized_coords: cl_bool, + addressing_mode: cl_addressing_mode, + filter_mode: cl_filter_mode, +) -> CLResult { + create_sampler_impl( + context, + normalized_coords, + addressing_mode, + filter_mode, + None, + ) +} + +pub fn create_sampler_with_properties( + context: cl_context, + sampler_properties: *const cl_sampler_properties, +) -> CLResult { + let mut normalized_coords = CL_TRUE; + let mut addressing_mode = CL_ADDRESS_CLAMP; + let mut filter_mode = CL_FILTER_NEAREST; + + // CL_INVALID_VALUE if the same property name is specified more than once. + let sampler_properties = if sampler_properties.is_null() { + None + } else { + let sampler_properties = + Properties::from_ptr(sampler_properties).ok_or(CL_INVALID_VALUE)?; + for p in &sampler_properties.props { + match p.0 as u32 { + CL_SAMPLER_ADDRESSING_MODE => addressing_mode = p.1 as u32, + CL_SAMPLER_FILTER_MODE => filter_mode = p.1 as u32, + CL_SAMPLER_NORMALIZED_COORDS => normalized_coords = p.1 as u32, + // CL_INVALID_VALUE if the property name in sampler_properties is not a supported + // property name + _ => return Err(CL_INVALID_VALUE), + } + } + Some(sampler_properties) + }; + + create_sampler_impl( + context, + normalized_coords, + addressing_mode, + filter_mode, + sampler_properties, + ) +} + pub fn enqueue_read_buffer( command_queue: cl_command_queue, buffer: cl_mem, diff --git a/src/gallium/frontends/rusticl/api/util.rs b/src/gallium/frontends/rusticl/api/util.rs index 84fe3783bc6..02e6e066909 100644 --- a/src/gallium/frontends/rusticl/api/util.rs +++ b/src/gallium/frontends/rusticl/api/util.rs @@ -6,6 +6,7 @@ use crate::api::types::*; use crate::core::event::*; use crate::core::queue::*; +use self::mesa_rust_util::properties::Properties; use self::mesa_rust_util::ptr::CheckedPtr; use self::rusticl_opencl_gen::*; @@ -168,16 +169,12 @@ where } } -impl CLProp for &Vec +impl CLProp for &T where T: CLProp, { fn cl_vec(&self) -> Vec { - let mut res: Vec = Vec::new(); - for i in *self { - res.append(&mut i.cl_vec()) - } - res + T::cl_vec(self) } } @@ -206,6 +203,30 @@ impl CLProp for *mut T { } } +impl CLProp for Properties +where + T: CLProp + Default, +{ + fn cl_vec(&self) -> Vec { + let mut res: Vec = Vec::new(); + for (k, v) in &self.props { + res.append(&mut k.cl_vec()); + res.append(&mut v.cl_vec()); + } + res.append(&mut T::default().cl_vec()); + res + } +} + +impl CLProp for Option +where + T: CLProp, +{ + fn cl_vec(&self) -> Vec { + self.as_ref().map_or(Vec::new(), |v| v.cl_vec()) + } +} + pub fn cl_prop(v: T) -> Vec { v.cl_vec() } diff --git a/src/gallium/frontends/rusticl/core/context.rs b/src/gallium/frontends/rusticl/core/context.rs index 77299d155d8..1c5686216fe 100644 --- a/src/gallium/frontends/rusticl/core/context.rs +++ b/src/gallium/frontends/rusticl/core/context.rs @@ -1,4 +1,5 @@ extern crate mesa_rust; +extern crate mesa_rust_util; extern crate rusticl_opencl_gen; use crate::api::icd::*; @@ -9,6 +10,7 @@ use crate::core::util::*; use crate::impl_cl_type_trait; use self::mesa_rust::pipe::resource::*; +use self::mesa_rust_util::properties::Properties; use self::rusticl_opencl_gen::*; use std::collections::HashMap; @@ -20,14 +22,17 @@ use std::sync::Mutex; pub struct Context { pub base: CLObjectBase, pub devs: Vec>, - pub properties: Vec, + pub properties: Properties, pub dtors: Mutex>>, } impl_cl_type_trait!(cl_context, Context, CL_INVALID_CONTEXT); impl Context { - pub fn new(devs: Vec>, properties: Vec) -> Arc { + pub fn new( + devs: Vec>, + properties: Properties, + ) -> Arc { Arc::new(Self { base: CLObjectBase::new(), devs: devs, diff --git a/src/gallium/frontends/rusticl/core/memory.rs b/src/gallium/frontends/rusticl/core/memory.rs index 699e0c4e39d..4470f6522ee 100644 --- a/src/gallium/frontends/rusticl/core/memory.rs +++ b/src/gallium/frontends/rusticl/core/memory.rs @@ -1,5 +1,6 @@ extern crate mesa_rust; extern crate mesa_rust_gen; +extern crate mesa_rust_util; extern crate rusticl_opencl_gen; use crate::api::icd::*; @@ -15,6 +16,7 @@ use self::mesa_rust::pipe::context::*; use self::mesa_rust::pipe::resource::*; use self::mesa_rust::pipe::transfer::*; use self::mesa_rust_gen::*; +use self::mesa_rust_util::properties::Properties; use self::rusticl_opencl_gen::*; use std::cmp; @@ -853,6 +855,7 @@ pub struct Sampler { pub normalized_coords: bool, pub addressing_mode: cl_addressing_mode, pub filter_mode: cl_filter_mode, + pub props: Option>, } impl_cl_type_trait!(cl_sampler, Sampler, CL_INVALID_SAMPLER); @@ -863,6 +866,7 @@ impl Sampler { normalized_coords: bool, addressing_mode: cl_addressing_mode, filter_mode: cl_filter_mode, + props: Option>, ) -> Arc { Arc::new(Self { base: CLObjectBase::new(), @@ -870,6 +874,7 @@ impl Sampler { normalized_coords: normalized_coords, addressing_mode: addressing_mode, filter_mode: filter_mode, + props: props, }) } }