rusticl: Enabling reading/writing for images created from buffers
authorAntonio Gomes <antoniospg100@gmail.com>
Tue, 6 Dec 2022 03:54:12 +0000 (00:54 -0300)
committerMarge Bot <emma+marge@anholt.net>
Tue, 7 Mar 2023 18:24:56 +0000 (18:24 +0000)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20378>

src/gallium/frontends/rusticl/api/memory.rs
src/gallium/frontends/rusticl/core/memory.rs

index fdb6a6a..f165942 100644 (file)
@@ -452,7 +452,7 @@ fn validate_image_desc(
         let p = p.get_arc()?;
         if !match desc.image_type {
             CL_MEM_OBJECT_IMAGE1D_BUFFER => p.is_buffer(),
-            CL_MEM_OBJECT_IMAGE2D => !p.is_buffer(),
+            CL_MEM_OBJECT_IMAGE2D => true,
             _ => false,
         } {
             return Err(CL_INVALID_OPERATION);
index c6754f3..9e140a8 100644 (file)
@@ -278,8 +278,9 @@ fn buffer_offset_size(
     region: &CLVec<usize>,
     row_pitch: usize,
     slice_pitch: usize,
+    pixel_size: usize,
 ) -> (usize, usize) {
-    let pitch = [1, row_pitch, slice_pitch];
+    let pitch = [pixel_size, row_pitch, slice_pitch];
     (*origin * pitch, *region * pitch)
 }
 
@@ -428,6 +429,14 @@ impl Mem {
         }))
     }
 
+    pub fn pixel_size(&self) -> Option<u8> {
+        if self.is_buffer() {
+            Some(1)
+        } else {
+            self.image_format.pixel_size()
+        }
+    }
+
     pub fn is_buffer(&self) -> bool {
         self.mem_type == CL_MEM_OBJECT_BUFFER
     }
@@ -443,8 +452,6 @@ impl Mem {
         let b = self.to_parent(&mut offset);
         let r = b.get_res()?.get(&q.device).unwrap();
 
-        assert!(self.is_buffer());
-
         Ok(ctx.buffer_map(
             r,
             offset.try_into().map_err(|_| CL_OUT_OF_HOST_MEMORY)?,
@@ -571,6 +578,14 @@ impl Mem {
         ptr::eq(a, b)
     }
 
+    pub fn is_parent_buffer(&self) -> bool {
+        self.parent.as_ref().map_or(false, |p| p.is_buffer())
+    }
+
+    pub fn is_image_from_buffer(&self) -> bool {
+        self.is_parent_buffer() && self.mem_type == CL_MEM_OBJECT_IMAGE2D
+    }
+
     fn get_res(&self) -> CLResult<&HashMap<Arc<Device>, Arc<PipeResource>>> {
         self.parent
             .as_ref()
@@ -658,7 +673,7 @@ impl Mem {
             let tx_dst;
 
             if self.is_buffer() {
-                let bpp = dst.image_format.pixel_size().unwrap() as usize;
+                let bpp = dst.pixel_size().unwrap() as usize;
                 tx_src = self.tx(q, ctx, src_origin[0], region.pixels() * bpp, RWFlags::RD)?;
                 tx_dst = dst.tx_image(
                     q,
@@ -680,7 +695,7 @@ impl Mem {
                     bpp as u8,
                 )
             } else {
-                let bpp = self.image_format.pixel_size().unwrap() as usize;
+                let bpp = self.pixel_size().unwrap() as usize;
                 tx_src = self.tx_image(
                     q,
                     ctx,
@@ -751,10 +766,7 @@ impl Mem {
         // make sure we allocate multiples of 4 bytes so drivers don't read out of bounds or
         // unaligned.
         // TODO: use div_ceil once it's available
-        let size = align(
-            self.image_format.pixel_size().unwrap() as usize,
-            size_of::<u32>(),
-        );
+        let size = align(self.pixel_size().unwrap() as usize, size_of::<u32>());
         let mut new_pattern: Vec<u32> = vec![0; size / size_of::<u32>()];
 
         // we don't support CL_DEPTH for now
@@ -793,9 +805,15 @@ impl Mem {
         dst_row_pitch: usize,
         dst_slice_pitch: usize,
     ) -> CLResult<()> {
-        if self.is_buffer() {
-            let (offset, size) =
-                buffer_offset_size(dst_origin, region, dst_row_pitch, dst_slice_pitch);
+        if self.is_buffer() || self.is_image_from_buffer() {
+            let pixel_size = self.pixel_size().unwrap();
+            let (offset, size) = buffer_offset_size(
+                dst_origin,
+                region,
+                dst_row_pitch,
+                dst_slice_pitch,
+                pixel_size.try_into().unwrap(),
+            );
             let tx = self.tx(q, ctx, offset, size, RWFlags::WR)?;
 
             sw_copy(
@@ -808,7 +826,7 @@ impl Mem {
                 &CLVec::default(),
                 dst_row_pitch,
                 dst_slice_pitch,
-                1,
+                pixel_size,
             );
         } else {
             assert!(dst_row_pitch == self.image_desc.image_row_pitch);
@@ -853,11 +871,16 @@ impl Mem {
         let tx;
         let pixel_size;
 
-        if self.is_buffer() {
-            let (offset, size) =
-                buffer_offset_size(src_origin, region, src_row_pitch, src_slice_pitch);
+        if self.is_buffer() || self.is_image_from_buffer() {
+            pixel_size = self.pixel_size().unwrap();
+            let (offset, size) = buffer_offset_size(
+                src_origin,
+                region,
+                src_row_pitch,
+                src_slice_pitch,
+                pixel_size.try_into().unwrap(),
+            );
             tx = self.tx(q, ctx, offset, size, RWFlags::RD)?;
-            pixel_size = 1;
         } else {
             assert!(dst_origin == &CLVec::default());
 
@@ -866,7 +889,7 @@ impl Mem {
             src_row_pitch = tx.row_pitch() as usize;
             src_slice_pitch = tx.slice_pitch() as usize;
 
-            pixel_size = self.image_format.pixel_size().unwrap();
+            pixel_size = self.pixel_size().unwrap();
         };
 
         sw_copy(
@@ -901,10 +924,12 @@ impl Mem {
         assert!(self.is_buffer());
         assert!(dst.is_buffer());
 
-        let (offset, size) = buffer_offset_size(src_origin, region, src_row_pitch, src_slice_pitch);
+        let (offset, size) =
+            buffer_offset_size(src_origin, region, src_row_pitch, src_slice_pitch, 1);
         let tx_src = self.tx(q, ctx, offset, size, RWFlags::RD)?;
 
-        let (offset, size) = buffer_offset_size(dst_origin, region, dst_row_pitch, dst_slice_pitch);
+        let (offset, size) =
+            buffer_offset_size(dst_origin, region, dst_row_pitch, dst_slice_pitch, 1);
         let tx_dst = dst.tx(q, ctx, offset, size, RWFlags::WR)?;
 
         // TODO check to use hw accelerated paths (e.g. resource_copy_region or blits)
@@ -1089,7 +1114,7 @@ impl Mem {
             ptr.add(
                 *origin
                     * [
-                        self.image_format.pixel_size().unwrap() as usize,
+                        self.pixel_size().unwrap() as usize,
                         *row_pitch,
                         *slice_pitch,
                     ],