gallium, rusticl: Add tex2d_from_buf in image_view and sampler_view
authorAntonio Gomes <antoniospg100@gmail.com>
Mon, 12 Dec 2022 20:35:49 +0000 (17:35 -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/auxiliary/util/u_sampler.c
src/gallium/frontends/rusticl/core/kernel.rs
src/gallium/frontends/rusticl/core/memory.rs
src/gallium/frontends/rusticl/mesa/pipe/context.rs
src/gallium/frontends/rusticl/mesa/pipe/resource.rs
src/gallium/include/pipe/p_defines.h
src/gallium/include/pipe/p_state.h

index d1d7470..daa5dc3 100644 (file)
@@ -46,6 +46,7 @@ default_template(struct pipe_sampler_view *view,
     */
 
    view->target = texture->target;
+   view->is_tex2d_from_buf = false;
    view->format = format;
    view->u.tex.first_level = 0;
    view->u.tex.last_level = texture->last_level;
index a043407..fc102f1 100644 (file)
@@ -940,6 +940,18 @@ impl Kernel {
                 KernelArgValue::Constant(c) => input.extend_from_slice(c),
                 KernelArgValue::MemObject(mem) => {
                     let res = mem.get_res_of_dev(&q.device)?;
+                    // If resource is a buffer and mem a 2D image, the 2d image was created from a
+                    // buffer. Use strides and dimensions of 2d image
+                    let app_img_info =
+                        if res.as_ref().is_buffer() && mem.mem_type == CL_MEM_OBJECT_IMAGE2D {
+                            Some(AppImgInfo::new(
+                                mem.image_desc.row_pitch()? / mem.image_elem_size as u32,
+                                mem.image_desc.width()?,
+                                mem.image_desc.height()?,
+                            ))
+                        } else {
+                            None
+                        };
                     if mem.is_buffer() {
                         if q.device.address_bits() == 64 {
                             input.extend_from_slice(&mem.offset.to_ne_bytes());
@@ -950,13 +962,13 @@ impl Kernel {
                     } else {
                         let format = mem.image_format.to_pipe_format().unwrap();
                         let (formats, orders) = if arg.kind == KernelArgType::Image {
-                            iviews.push(res.pipe_image_view(format, false));
+                            iviews.push(res.pipe_image_view(format, false, app_img_info.as_ref()));
                             (&mut img_formats, &mut img_orders)
                         } else if arg.kind == KernelArgType::RWImage {
-                            iviews.push(res.pipe_image_view(format, true));
+                            iviews.push(res.pipe_image_view(format, true, app_img_info.as_ref()));
                             (&mut img_formats, &mut img_orders)
                         } else {
-                            sviews.push((res.clone(), format));
+                            sviews.push((res.clone(), format, app_img_info));
                             (&mut tex_formats, &mut tex_orders)
                         };
 
@@ -1060,7 +1072,7 @@ impl Kernel {
 
             let mut sviews: Vec<_> = sviews
                 .iter()
-                .map(|(s, f)| ctx.create_sampler_view(s, *f))
+                .map(|(s, f, aii)| ctx.create_sampler_view(s, *f, aii.as_ref()))
                 .collect();
             let samplers: Vec<_> = samplers
                 .iter()
index b781348..770aee9 100644 (file)
@@ -128,6 +128,8 @@ pub trait CLImageDescInfo {
     fn bx(&self) -> CLResult<pipe_box>;
     fn row_pitch(&self) -> CLResult<u32>;
     fn slice_pitch(&self) -> CLResult<u32>;
+    fn width(&self) -> CLResult<u32>;
+    fn height(&self) -> CLResult<u32>;
     fn size(&self) -> CLVec<usize>;
     fn api_size(&self) -> CLVec<usize>;
 
@@ -223,6 +225,18 @@ impl CLImageDescInfo for cl_image_desc {
             .try_into()
             .map_err(|_| CL_OUT_OF_HOST_MEMORY)
     }
+
+    fn width(&self) -> CLResult<u32> {
+        self.image_width
+            .try_into()
+            .map_err(|_| CL_OUT_OF_HOST_MEMORY)
+    }
+
+    fn height(&self) -> CLResult<u32> {
+        self.image_height
+            .try_into()
+            .map_err(|_| CL_OUT_OF_HOST_MEMORY)
+    }
 }
 
 fn sw_copy(
index 835fff1..a4d83fc 100644 (file)
@@ -409,14 +409,18 @@ impl PipeContext {
         &self,
         res: &PipeResource,
         format: pipe_format,
+        app_img_info: Option<&AppImgInfo>,
     ) -> *mut pipe_sampler_view {
-        let template = res.pipe_sampler_view_template(format);
+        let template = res.pipe_sampler_view_template(format, app_img_info);
+
         unsafe {
-            self.pipe.as_ref().create_sampler_view.unwrap()(
+            let s_view = self.pipe.as_ref().create_sampler_view.unwrap()(
                 self.pipe.as_ptr(),
                 res.pipe(),
                 &template,
-            )
+            );
+
+            s_view
         }
     }
 
index 938e970..09f2d84 100644 (file)
@@ -7,6 +7,25 @@ pub struct PipeResource {
     pub is_user: bool,
 }
 
+// Image dimensions provide by application to be used in both
+// image and sampler views when image is created from buffer
+#[derive(PartialEq, Eq)]
+pub struct AppImgInfo {
+    row_stride: u32,
+    width: u32,
+    height: u32,
+}
+
+impl AppImgInfo {
+    pub fn new(row_stride: u32, width: u32, height: u32) -> AppImgInfo {
+        AppImgInfo {
+            row_stride: row_stride,
+            width: width,
+            height: height,
+        }
+    }
+}
+
 impl PipeResource {
     pub fn new(res: *mut pipe_resource, is_user: bool) -> Option<Self> {
         if res.is_null() {
@@ -43,8 +62,26 @@ impl PipeResource {
         unsafe { self.pipe.as_ref().unwrap().array_size }
     }
 
-    pub fn pipe_image_view(&self, format: pipe_format, read_write: bool) -> pipe_image_view {
-        let u = if self.as_ref().target() == pipe_texture_target::PIPE_BUFFER {
+    pub fn is_buffer(&self) -> bool {
+        self.as_ref().target() == pipe_texture_target::PIPE_BUFFER
+    }
+
+    pub fn pipe_image_view(
+        &self,
+        format: pipe_format,
+        read_write: bool,
+        app_img_info: Option<&AppImgInfo>,
+    ) -> pipe_image_view {
+        let u = if let Some(app_img_info) = app_img_info {
+            pipe_image_view__bindgen_ty_1 {
+                tex2d_from_buf: pipe_image_view__bindgen_ty_1__bindgen_ty_3 {
+                    offset: 0,
+                    row_stride: app_img_info.row_stride as u16,
+                    width: app_img_info.width as u16,
+                    height: app_img_info.height as u16,
+                },
+            }
+        } else if self.is_buffer() {
             pipe_image_view__bindgen_ty_1 {
                 buf: pipe_image_view__bindgen_ty_1__bindgen_ty_2 {
                     offset: 0,
@@ -72,22 +109,40 @@ impl PipeResource {
             PIPE_IMAGE_ACCESS_WRITE
         } as u16;
 
+        let access = if app_img_info.is_some() {
+            PIPE_IMAGE_ACCESS_TEX2D_FROM_BUFFER
+        } else {
+            0
+        } as u16;
+
         pipe_image_view {
             resource: self.pipe(),
             format: format,
-            access: 0,
+            access: access,
             shader_access: shader_access,
             u: u,
         }
     }
 
-    pub fn pipe_sampler_view_template(&self, format: pipe_format) -> pipe_sampler_view {
+    pub fn pipe_sampler_view_template(
+        &self,
+        format: pipe_format,
+        app_img_info: Option<&AppImgInfo>,
+    ) -> pipe_sampler_view {
         let mut res = pipe_sampler_view::default();
         unsafe {
             u_sampler_view_default_template(&mut res, self.pipe, format);
         }
 
-        if res.target() == pipe_texture_target::PIPE_BUFFER {
+        if let Some(app_img_info) = app_img_info {
+            res.u.tex2d_from_buf.offset = 0;
+            res.u.tex2d_from_buf.row_stride = app_img_info.row_stride as u16;
+            res.u.tex2d_from_buf.width = app_img_info.width as u16;
+            res.u.tex2d_from_buf.height = app_img_info.height as u16;
+
+            res.set_is_tex2d_from_buf(true);
+        } else if res.target() == pipe_texture_target::PIPE_BUFFER {
+            res.u.buf.offset = 0;
             res.u.buf.size = self.as_ref().width0;
         }
 
index 5cf3ce6..d7d0510 100644 (file)
@@ -724,12 +724,13 @@ enum pipe_conservative_raster_mode
 /**
  * pipe_image_view access flags.
  */
-#define PIPE_IMAGE_ACCESS_READ       (1 << 0)
-#define PIPE_IMAGE_ACCESS_WRITE      (1 << 1)
-#define PIPE_IMAGE_ACCESS_READ_WRITE (PIPE_IMAGE_ACCESS_READ | \
-                                      PIPE_IMAGE_ACCESS_WRITE)
-#define PIPE_IMAGE_ACCESS_COHERENT   (1 << 2)
-#define PIPE_IMAGE_ACCESS_VOLATILE   (1 << 3)
+#define PIPE_IMAGE_ACCESS_READ               (1 << 0)
+#define PIPE_IMAGE_ACCESS_WRITE              (1 << 1)
+#define PIPE_IMAGE_ACCESS_READ_WRITE         (PIPE_IMAGE_ACCESS_READ | \
+                                              PIPE_IMAGE_ACCESS_WRITE)
+#define PIPE_IMAGE_ACCESS_COHERENT           (1 << 2)
+#define PIPE_IMAGE_ACCESS_VOLATILE           (1 << 3)
+#define PIPE_IMAGE_ACCESS_TEX2D_FROM_BUFFER  (1 << 4)
 
 /**
  * Implementation capabilities/limits which are queried through
index 6ebc986..c62dd3c 100644 (file)
@@ -487,7 +487,8 @@ struct pipe_sampler_view
    /* Put the refcount on its own cache line to prevent "False sharing". */
    EXCLUSIVE_CACHELINE(struct pipe_reference reference);
 
-   enum pipe_format format:15;      /**< typed PIPE_FORMAT_x */
+   enum pipe_format format:14;      /**< typed PIPE_FORMAT_x */
+   bool is_tex2d_from_buf:1;       /**< true if union is tex2d_from_buf */
    enum pipe_texture_target target:5; /**< PIPE_TEXTURE_x */
    unsigned swizzle_r:3;         /**< PIPE_SWIZZLE_x for red component */
    unsigned swizzle_g:3;         /**< PIPE_SWIZZLE_x for green component */
@@ -506,6 +507,12 @@ struct pipe_sampler_view
          unsigned offset;   /**< offset in bytes */
          unsigned size;     /**< size of the readable sub-range in bytes */
       } buf;
+      struct {
+         unsigned offset;  /**< offset in pixels */
+         uint16_t row_stride; /**< size of the image row_stride in pixels */
+         uint16_t width;      /**< width of image provided by application */
+         uint16_t height;     /**< height of image provided by application */
+      } tex2d_from_buf;      /**< used in cl extension cl_khr_image2d_from_buffer */
    } u;
 };
 
@@ -524,7 +531,6 @@ struct pipe_image_view
    enum pipe_format format;      /**< typed PIPE_FORMAT_x */
    uint16_t access;              /**< PIPE_IMAGE_ACCESS_x */
    uint16_t shader_access;       /**< PIPE_IMAGE_ACCESS_x */
-
    union {
       struct {
          unsigned first_layer:16;     /**< first layer to use for array textures */
@@ -535,6 +541,12 @@ struct pipe_image_view
          unsigned offset;   /**< offset in bytes */
          unsigned size;     /**< size of the accessible sub-range in bytes */
       } buf;
+      struct {
+         unsigned offset;   /**< offset in pixels */
+         uint16_t row_stride;     /**< size of the image row_stride in pixels */
+         uint16_t width;     /**< width of image provided by application */
+         uint16_t height;     /**< height of image provided by application */
+      } tex2d_from_buf;      /**< used in cl extension cl_khr_image2d_from_buffer */
    } u;
 };