rusticl/queue: implement missing CL 3.0 bits
authorKarol Herbst <kherbst@redhat.com>
Tue, 12 Apr 2022 12:52:57 +0000 (14:52 +0200)
committerMarge Bot <emma+marge@anholt.net>
Mon, 12 Sep 2022 05:58:13 +0000 (05:58 +0000)
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15439>

src/gallium/frontends/rusticl/api/device.rs
src/gallium/frontends/rusticl/api/icd.rs
src/gallium/frontends/rusticl/api/queue.rs
src/gallium/frontends/rusticl/core/queue.rs

index b1d5049..3f0c8c7 100644 (file)
@@ -262,3 +262,11 @@ pub fn get_host_timer(_device: cl_device_id, _host_timestamp: *mut cl_ulong) ->
     // TODO: we could support it
     Err(CL_INVALID_OPERATION)
 }
+
+pub fn set_default_device_command_queue(
+    _context: cl_context,
+    _device: cl_device_id,
+    _command_queue: cl_command_queue,
+) -> CLResult<()> {
+    Err(CL_INVALID_OPERATION)
+}
index c3fb7cd..3a59ab5 100644 (file)
@@ -165,7 +165,7 @@ pub static DISPATCH: cl_icd_dispatch = cl_icd_dispatch {
     clGetDeviceAndHostTimer: Some(cl_get_device_and_host_timer),
     clGetHostTimer: Some(cl_get_host_timer),
     clGetKernelSubGroupInfo: Some(cl_get_kernel_sub_group_info),
-    clSetDefaultDeviceCommandQueue: None,
+    clSetDefaultDeviceCommandQueue: Some(cl_set_default_device_command_queue),
     clSetProgramReleaseCallback: Some(cl_set_program_release_callback),
     clSetProgramSpecializationConstant: Some(cl_set_program_specialization_constant),
     clCreateBufferWithProperties: Some(cl_create_buffer_with_properties),
@@ -1594,11 +1594,13 @@ extern "C" fn cl_enqueue_barrier_with_wait_list(
 extern "C" fn cl_create_command_queue_with_properties(
     context: cl_context,
     device: cl_device_id,
-    _arg3: *const cl_queue_properties,
+    properties: *const cl_queue_properties,
     errcode_ret: *mut cl_int,
 ) -> cl_command_queue {
-    // TODO use own impl, this is enough to run the CL 3.0 CTS
-    match_obj!(create_command_queue(context, device, 0), errcode_ret)
+    match_obj!(
+        create_command_queue_with_properties(context, device, properties),
+        errcode_ret
+    )
 }
 
 extern "C" fn cl_create_pipe(
@@ -1790,6 +1792,18 @@ extern "C" fn cl_get_kernel_sub_group_info(
     ))
 }
 
+extern "C" fn cl_set_default_device_command_queue(
+    context: cl_context,
+    device: cl_device_id,
+    command_queue: cl_command_queue,
+) -> cl_int {
+    match_err!(set_default_device_command_queue(
+        context,
+        device,
+        command_queue,
+    ))
+}
+
 extern "C" fn cl_set_program_release_callback(
     program: cl_program,
     pfn_notify: ::std::option::Option<ProgramCB>,
index b1699fa..e67a4b5 100644 (file)
@@ -1,3 +1,4 @@
+extern crate mesa_rust_util;
 extern crate rusticl_opencl_gen;
 
 use crate::api::event::create_and_queue;
@@ -6,8 +7,10 @@ use crate::api::util::*;
 use crate::core::event::*;
 use crate::core::queue::*;
 
+use self::mesa_rust_util::properties::*;
 use self::rusticl_opencl_gen::*;
 
+use std::ptr;
 use std::sync::Arc;
 
 impl CLInfo<cl_command_queue_info> for cl_command_queue {
@@ -24,8 +27,15 @@ impl CLInfo<cl_command_queue_info> for cl_command_queue {
                 let ptr = Arc::as_ptr(&queue.device);
                 cl_prop::<cl_device_id>(cl_device_id::from_ptr(ptr))
             }
+            CL_QUEUE_DEVICE_DEFAULT => cl_prop::<cl_command_queue>(ptr::null_mut()),
             CL_QUEUE_PROPERTIES => cl_prop::<cl_command_queue_properties>(queue.props),
+            CL_QUEUE_PROPERTIES_ARRAY => {
+                cl_prop::<&Option<Properties<cl_queue_properties>>>(&queue.props_v2)
+            }
             CL_QUEUE_REFERENCE_COUNT => cl_prop::<cl_uint>(self.refcnt()?),
+            // clGetCommandQueueInfo, passing CL_QUEUE_SIZE Returns CL_INVALID_COMMAND_QUEUE since
+            // command_queue cannot be a valid device command-queue.
+            CL_QUEUE_SIZE => return Err(CL_INVALID_COMMAND_QUEUE),
             // CL_INVALID_VALUE if param_name is not one of the supported values
             _ => return Err(CL_INVALID_VALUE),
         })
@@ -43,18 +53,16 @@ fn supported_command_queue_properties(properties: cl_command_queue_properties) -
     properties & !valid_flags == 0
 }
 
-pub fn create_command_queue(
+pub fn create_command_queue_impl(
     context: cl_context,
     device: cl_device_id,
     properties: cl_command_queue_properties,
+    properties_v2: Option<Properties<cl_queue_properties>>,
 ) -> CLResult<cl_command_queue> {
-    // CL_INVALID_CONTEXT if context is not a valid context.
     let c = context.get_arc()?;
-
-    // CL_INVALID_DEVICE if device is not a valid device
     let d = device.get_arc()?;
 
-    // ... or is not associated with context.
+    // CL_INVALID_DEVICE if device [...] is not associated with context.
     if !c.devs.contains(&d) {
         return Err(CL_INVALID_DEVICE);
     }
@@ -69,7 +77,55 @@ pub fn create_command_queue(
         return Err(CL_INVALID_QUEUE_PROPERTIES);
     }
 
-    Ok(cl_command_queue::from_arc(Queue::new(c, d, properties)?))
+    Ok(cl_command_queue::from_arc(Queue::new(
+        c,
+        d,
+        properties,
+        properties_v2,
+    )?))
+}
+
+pub fn create_command_queue(
+    context: cl_context,
+    device: cl_device_id,
+    properties: cl_command_queue_properties,
+) -> CLResult<cl_command_queue> {
+    create_command_queue_impl(context, device, properties, None)
+}
+
+pub fn create_command_queue_with_properties(
+    context: cl_context,
+    device: cl_device_id,
+    properties: *const cl_queue_properties,
+) -> CLResult<cl_command_queue> {
+    let c = context.get_arc()?;
+    let d = device.get_arc()?;
+
+    let mut queue_properties = cl_command_queue_properties::default();
+    let properties = if properties.is_null() {
+        None
+    } else {
+        let properties = Properties::from_ptr(properties).ok_or(CL_INVALID_PROPERTY)?;
+
+        for (k, v) in &properties.props {
+            match *k as cl_uint {
+                CL_QUEUE_PROPERTIES => queue_properties = *v,
+                // CL_INVALID_QUEUE_PROPERTIES if values specified in properties are valid but are not
+                // supported by the device.
+                CL_QUEUE_SIZE => return Err(CL_INVALID_QUEUE_PROPERTIES),
+                _ => return Err(CL_INVALID_PROPERTY),
+            }
+        }
+
+        Some(properties)
+    };
+
+    Ok(cl_command_queue::from_arc(Queue::new(
+        c,
+        d,
+        queue_properties,
+        properties,
+    )?))
 }
 
 pub fn enqueue_marker(command_queue: cl_command_queue, event: *mut cl_event) -> CLResult<()> {
index 543d178..35dd4b0 100644 (file)
@@ -1,4 +1,4 @@
-extern crate mesa_rust;
+extern crate mesa_rust_util;
 extern crate rusticl_opencl_gen;
 
 use crate::api::icd::*;
@@ -7,6 +7,7 @@ use crate::core::device::*;
 use crate::core::event::*;
 use crate::impl_cl_type_trait;
 
+use self::mesa_rust_util::properties::*;
 use self::rusticl_opencl_gen::*;
 
 use std::sync::mpsc;
@@ -21,6 +22,7 @@ pub struct Queue {
     pub context: Arc<Context>,
     pub device: Arc<Device>,
     pub props: cl_command_queue_properties,
+    pub props_v2: Option<Properties<cl_queue_properties>>,
     pending: Mutex<Vec<Arc<Event>>>,
     _thrd: Option<JoinHandle<()>>,
     chan_in: mpsc::Sender<Vec<Arc<Event>>>,
@@ -33,6 +35,7 @@ impl Queue {
         context: Arc<Context>,
         device: Arc<Device>,
         props: cl_command_queue_properties,
+        props_v2: Option<Properties<cl_queue_properties>>,
     ) -> CLResult<Arc<Queue>> {
         // we assume that memory allocation is the only possible failure. Any other failure reason
         // should be detected earlier (e.g.: checking for CAPs).
@@ -43,6 +46,7 @@ impl Queue {
             context: context,
             device: device,
             props: props,
+            props_v2: props_v2,
             pending: Mutex::new(Vec::new()),
             _thrd: Some(
                 thread::Builder::new()