diff --git a/src/gallium/frontends/rusticl/api/icd.rs b/src/gallium/frontends/rusticl/api/icd.rs index c915eae5248..4d89d707b04 100644 --- a/src/gallium/frontends/rusticl/api/icd.rs +++ b/src/gallium/frontends/rusticl/api/icd.rs @@ -1476,17 +1476,25 @@ extern "C" fn cl_enqueue_fill_buffer( } extern "C" fn cl_enqueue_fill_image( - _command_queue: cl_command_queue, - _image: cl_mem, - _fill_color: *const ::std::os::raw::c_void, - _origin: *const [usize; 3usize], - _region: *const [usize; 3usize], - _num_events_in_wait_list: cl_uint, - _event_wait_list: *const cl_event, - _event: *mut cl_event, + command_queue: cl_command_queue, + image: cl_mem, + fill_color: *const ::std::os::raw::c_void, + origin: *const [usize; 3usize], + region: *const [usize; 3usize], + num_events_in_wait_list: cl_uint, + event_wait_list: *const cl_event, + event: *mut cl_event, ) -> cl_int { - println!("cl_enqueue_fill_image not implemented"); - CL_OUT_OF_HOST_MEMORY + match_err!(enqueue_fill_image( + command_queue, + image, + fill_color, + origin, + region, + num_events_in_wait_list, + event_wait_list, + event, + )) } extern "C" fn cl_enqueue_migrate_mem_objects( diff --git a/src/gallium/frontends/rusticl/api/memory.rs b/src/gallium/frontends/rusticl/api/memory.rs index f053587e91a..9609da9aff1 100644 --- a/src/gallium/frontends/rusticl/api/memory.rs +++ b/src/gallium/frontends/rusticl/api/memory.rs @@ -1676,6 +1676,53 @@ pub fn enqueue_copy_image( Err(CL_OUT_OF_HOST_MEMORY) } +pub fn enqueue_fill_image( + command_queue: cl_command_queue, + image: cl_mem, + fill_color: *const ::std::os::raw::c_void, + origin: *const [usize; 3], + region: *const [usize; 3], + num_events_in_wait_list: cl_uint, + event_wait_list: *const cl_event, + event: *mut cl_event, +) -> CLResult<()> { + let q = command_queue.get_arc()?; + let i = image.get_arc()?; + let evs = event_list_from_cl(&q, num_events_in_wait_list, event_wait_list)?; + + // CL_INVALID_CONTEXT if the context associated with command_queue and image are not the same + if i.context != q.context { + return Err(CL_INVALID_CONTEXT); + } + + // CL_INVALID_VALUE if fill_color is NULL. + // CL_INVALID_VALUE if origin or region is NULL. + if fill_color.is_null() || origin.is_null() || region.is_null() { + return Err(CL_INVALID_VALUE); + } + + let region = unsafe { CLVec::from_raw(region.cast()) }; + let origin = unsafe { CLVec::from_raw(origin.cast()) }; + + // we have to copy memory and it's always a 4 component int value + // TODO but not for CL_DEPTH + let fill_color = unsafe { slice::from_raw_parts(fill_color.cast(), 4).to_vec() }; + create_and_queue( + q, + CL_COMMAND_FILL_BUFFER, + evs, + event, + false, + Box::new(move |q, ctx| i.fill_image(q, ctx, &fill_color, &origin, ®ion)), + ) + + //• CL_INVALID_VALUE if the region being filled as specified by origin and region is out of bounds. + //• CL_INVALID_VALUE if values in origin and region do not follow rules described in the argument description for origin and region. + //• CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified or compute row and/or slice pitch) for image are not supported by device associated with queue. + //• CL_IMAGE_FORMAT_NOT_SUPPORTED if image format (image channel order and data type) for + //image are not supported by device associated with queue. +} + pub fn enqueue_map_image( command_queue: cl_command_queue, image: cl_mem, diff --git a/src/gallium/frontends/rusticl/core/memory.rs b/src/gallium/frontends/rusticl/core/memory.rs index 9285bfefce1..bf6b287bf26 100644 --- a/src/gallium/frontends/rusticl/core/memory.rs +++ b/src/gallium/frontends/rusticl/core/memory.rs @@ -506,6 +506,34 @@ impl Mem { Ok(()) } + pub fn fill_image( + &self, + q: &Arc, + ctx: &Arc, + pattern: &[u32], + origin: &CLVec, + region: &CLVec, + ) -> CLResult<()> { + assert!(!self.is_buffer()); + + let res = self.get_res()?.get(&q.device).unwrap(); + let bx = create_box(origin, region, self.mem_type)?; + let mut new_pattern = vec![0; self.image_format.pixel_size().unwrap() as usize]; + + unsafe { + util_format_pack_rgba( + self.image_format.to_pipe_format().unwrap(), + new_pattern.as_mut_ptr().cast(), + pattern.as_ptr().cast(), + 1, + ); + } + + ctx.clear_texture(res, &new_pattern, &bx); + + Ok(()) + } + pub fn write_from_user_rect( &self, src: *const c_void, diff --git a/src/gallium/frontends/rusticl/mesa/pipe/context.rs b/src/gallium/frontends/rusticl/mesa/pipe/context.rs index 6aa5784b4e4..4ffca4b5b4e 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe/context.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe/context.rs @@ -90,6 +90,18 @@ impl PipeContext { } } + pub fn clear_texture(&self, res: &PipeResource, pattern: &[u8], bx: &pipe_box) { + unsafe { + self.pipe.as_ref().clear_texture.unwrap()( + self.pipe.as_ptr(), + res.pipe(), + 0, + bx, + pattern.as_ptr().cast(), + ) + } + } + pub fn resource_copy_region( &self, src: &PipeResource, @@ -291,6 +303,7 @@ fn has_required_cbs(c: &pipe_context) -> bool { && c.buffer_subdata.is_some() && c.buffer_unmap.is_some() && c.clear_buffer.is_some() + && c.clear_texture.is_some() && c.create_compute_state.is_some() && c.delete_compute_state.is_some() && c.flush.is_some() diff --git a/src/gallium/frontends/rusticl/meson.build b/src/gallium/frontends/rusticl/meson.build index d746e7c223b..4f642a6bbda 100644 --- a/src/gallium/frontends/rusticl/meson.build +++ b/src/gallium/frontends/rusticl/meson.build @@ -200,6 +200,7 @@ rusticl_mesa_bindings_rs = rust.bindgen( '--whitelist-function', 'rz?alloc_.*', '--whitelist-function', 'spirv_.*', '--whitelist-function', 'u_.*', + '--whitelist-function', 'util_format_.*', '--whitelist-type', 'pipe_endian', '--whitelist-type', 'clc_kernel_arg_access_qualifier', '--bitfield-enum', 'clc_kernel_arg_access_qualifier', diff --git a/src/gallium/frontends/rusticl/rusticl_mesa_inline_bindings_wrapper.c b/src/gallium/frontends/rusticl/rusticl_mesa_inline_bindings_wrapper.c index 80333f5a363..269659507fd 100644 --- a/src/gallium/frontends/rusticl/rusticl_mesa_inline_bindings_wrapper.c +++ b/src/gallium/frontends/rusticl/rusticl_mesa_inline_bindings_wrapper.c @@ -5,3 +5,9 @@ pipe_resource_reference(struct pipe_resource **dst, struct pipe_resource *src) { __pipe_resource_reference_wraped(dst, src); } + +void +util_format_pack_rgba(enum pipe_format format, void *dst, const void *src, unsigned w) +{ + return __util_format_pack_rgba(format, dst, src, w); +} diff --git a/src/gallium/frontends/rusticl/rusticl_mesa_inline_bindings_wrapper.h b/src/gallium/frontends/rusticl/rusticl_mesa_inline_bindings_wrapper.h index 36f5f202e83..9a7ab2c1937 100644 --- a/src/gallium/frontends/rusticl/rusticl_mesa_inline_bindings_wrapper.h +++ b/src/gallium/frontends/rusticl/rusticl_mesa_inline_bindings_wrapper.h @@ -1,5 +1,9 @@ #define pipe_resource_reference __pipe_resource_reference_wraped +#define util_format_pack_rgba __util_format_pack_rgba #include "util/u_inlines.h" +#include "util/format/u_format.h" #undef pipe_resource_reference +#undef util_format_pack_rgba void pipe_resource_reference(struct pipe_resource **dst, struct pipe_resource *src); +void util_format_pack_rgba(enum pipe_format format, void *dst, const void *src, unsigned w);