From 5160bff15d64e345ad9dd49e34d6e948f060a4dd Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Thu, 24 Mar 2022 18:21:44 +0100 Subject: [PATCH] rusticl/mem: implement copy image Signed-off-by: Karol Herbst Acked-by: Alyssa Rosenzweig Part-of: --- src/gallium/frontends/rusticl/api/memory.rs | 72 ++++++++++++++++++---- src/gallium/frontends/rusticl/api/types.rs | 28 +++++++++ src/gallium/frontends/rusticl/core/memory.rs | 26 ++++---- src/gallium/frontends/rusticl/mesa/pipe/context.rs | 21 ++----- 4 files changed, 106 insertions(+), 41 deletions(-) diff --git a/src/gallium/frontends/rusticl/api/memory.rs b/src/gallium/frontends/rusticl/api/memory.rs index 9609da9..1f0e6f0 100644 --- a/src/gallium/frontends/rusticl/api/memory.rs +++ b/src/gallium/frontends/rusticl/api/memory.rs @@ -983,7 +983,16 @@ pub fn enqueue_copy_buffer( evs, event, false, - Box::new(move |q, ctx| src.copy_to(q, ctx, &dst, src_offset, dst_offset, size)), + Box::new(move |q, ctx| { + src.copy_to( + q, + ctx, + &dst, + CLVec::new([src_offset, 0, 0]), + CLVec::new([dst_offset, 0, 0]), + &CLVec::new([size, 1, 1]), + ) + }), ) // TODO @@ -1662,18 +1671,57 @@ pub fn enqueue_write_image( } pub fn enqueue_copy_image( - _command_queue: cl_command_queue, - _src_image: cl_mem, - _dst_image: cl_mem, - _src_origin: *const usize, - _dst_origin: *const usize, - _region: *const usize, - _num_events_in_wait_list: cl_uint, - _event_wait_list: *const cl_event, - _event: *mut cl_event, + command_queue: cl_command_queue, + src_image: cl_mem, + dst_image: cl_mem, + src_origin: *const usize, + dst_origin: *const usize, + region: *const usize, + num_events_in_wait_list: cl_uint, + event_wait_list: *const cl_event, + event: *mut cl_event, ) -> CLResult<()> { - println!("enqueue_copy_image not implemented"); - Err(CL_OUT_OF_HOST_MEMORY) + let q = command_queue.get_arc()?; + let src_image = src_image.get_arc()?; + let dst_image = dst_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, src_image and dst_image are not the same + if src_image.context != q.context || dst_image.context != q.context { + return Err(CL_INVALID_CONTEXT); + } + + // CL_IMAGE_FORMAT_MISMATCH if src_image and dst_image do not use the same image format. + if src_image.image_format != dst_image.image_format { + return Err(CL_IMAGE_FORMAT_MISMATCH); + } + + // CL_INVALID_VALUE if src_origin, dst_origin, or region is NULL. + if src_origin.is_null() || dst_origin.is_null() || region.is_null() { + return Err(CL_INVALID_VALUE); + } + + let region = unsafe { CLVec::from_raw(region) }; + let dst_origin = unsafe { CLVec::from_raw(dst_origin) }; + let src_origin = unsafe { CLVec::from_raw(src_origin) }; + + create_and_queue( + q, + CL_COMMAND_COPY_IMAGE, + evs, + event, + false, + Box::new(move |q, ctx| { + src_image.copy_to(q, ctx, &dst_image, src_origin, dst_origin, ®ion) + }), + ) + + //• CL_INVALID_VALUE if the 2D or 3D rectangular region specified by src_origin and src_origin + region refers to a region outside src_image, or if the 2D or 3D rectangular region specified by dst_origin and dst_origin + region refers to a region outside dst_image. + //• CL_INVALID_VALUE if values in src_origin, dst_origin and region do not follow rules described in the argument description for src_origin, dst_origin and region. + //• CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified or compute row and/or slice pitch) for src_image or dst_image are not supported by device associated with queue. + //• CL_IMAGE_FORMAT_NOT_SUPPORTED if image format (image channel order and data type) for src_image or dst_image are not supported by device associated with queue. + //• CL_INVALID_OPERATION if the device associated with command_queue does not support images (i.e. CL_DEVICE_IMAGE_SUPPORT specified in the Device Queries table is CL_FALSE). + //• CL_MEM_COPY_OVERLAP if src_image and dst_image are the same image object and the source and destination regions overlap. } pub fn enqueue_fill_image( diff --git a/src/gallium/frontends/rusticl/api/types.rs b/src/gallium/frontends/rusticl/api/types.rs index 14f442a..5f1856f 100644 --- a/src/gallium/frontends/rusticl/api/types.rs +++ b/src/gallium/frontends/rusticl/api/types.rs @@ -78,6 +78,10 @@ pub struct CLVec { } impl CLVec { + pub fn new(vals: [T; 3]) -> Self { + Self { vals: vals } + } + /// # Safety /// /// This function is intended for use around OpenCL vectors of size 3. @@ -112,6 +116,12 @@ impl std::ops::Deref for CLVec { } } +impl std::ops::DerefMut for CLVec { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.vals + } +} + impl> std::ops::Add for CLVec { type Output = Self; @@ -161,3 +171,21 @@ where self[0] * other[0] + self[1] * other[1] + self[2] * other[2] } } + +impl TryInto<[T; 3]> for CLVec +where + S: Copy, + T: TryFrom, + [T; 3]: TryFrom>, +{ + type Error = cl_int; + + fn try_into(self) -> Result<[T; 3], cl_int> { + let vec: Result, _> = self + .vals + .iter() + .map(|v| T::try_from(*v).map_err(|_| CL_OUT_OF_HOST_MEMORY)) + .collect(); + vec?.try_into().map_err(|_| CL_OUT_OF_HOST_MEMORY) + } +} diff --git a/src/gallium/frontends/rusticl/core/memory.rs b/src/gallium/frontends/rusticl/core/memory.rs index bf6b287..30e4044 100644 --- a/src/gallium/frontends/rusticl/core/memory.rs +++ b/src/gallium/frontends/rusticl/core/memory.rs @@ -463,25 +463,23 @@ impl Mem { q: &Arc, ctx: &PipeContext, dst: &Arc, - mut src_offset: usize, - mut dst_offset: usize, - size: usize, + mut src_origin: CLVec, + mut dst_origin: CLVec, + region: &CLVec, ) -> CLResult<()> { - assert!(self.is_buffer()); - - let src = self.to_parent(&mut src_offset); - let dst = dst.to_parent(&mut dst_offset); + let src = self.to_parent(&mut src_origin[0]); + let dst = dst.to_parent(&mut dst_origin[0]); + let bx = create_box(&src_origin, region, self.mem_type)?; + let mut dst_origin: [u32; 3] = dst_origin.try_into()?; let src_res = src.get_res()?.get(&q.device).unwrap(); let dst_res = dst.get_res()?.get(&q.device).unwrap(); - ctx.resource_copy_region( - src_res, - src_offset.try_into().map_err(|_| CL_OUT_OF_HOST_MEMORY)?, - dst_res, - dst_offset.try_into().map_err(|_| CL_OUT_OF_HOST_MEMORY)?, - size.try_into().map_err(|_| CL_OUT_OF_HOST_MEMORY)?, - ); + if self.mem_type == CL_MEM_OBJECT_IMAGE1D_ARRAY { + (dst_origin[1], dst_origin[2]) = (dst_origin[2], dst_origin[1]); + } + + ctx.resource_copy_region(src_res, dst_res, &dst_origin, &bx); Ok(()) } diff --git a/src/gallium/frontends/rusticl/mesa/pipe/context.rs b/src/gallium/frontends/rusticl/mesa/pipe/context.rs index 4ffca4b..b46f407 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe/context.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe/context.rs @@ -105,30 +105,21 @@ impl PipeContext { pub fn resource_copy_region( &self, src: &PipeResource, - src_offset: i32, dst: &PipeResource, - dst_offset: u32, - size: i32, + dst_offset: &[u32; 3], + bx: &pipe_box, ) { - let b = pipe_box { - width: size, - height: 1, - depth: 1, - x: src_offset, - ..Default::default() - }; - unsafe { self.pipe.as_ref().resource_copy_region.unwrap()( self.pipe.as_ptr(), dst.pipe(), 0, - dst_offset, - 0, - 0, + dst_offset[0], + dst_offset[1], + dst_offset[2], src.pipe(), 0, - &b, + bx, ) } } -- 2.7.4