diff --git a/src/gallium/frontends/rusticl/core/memory.rs b/src/gallium/frontends/rusticl/core/memory.rs index e4b3dcbba63..ffa5979c273 100644 --- a/src/gallium/frontends/rusticl/core/memory.rs +++ b/src/gallium/frontends/rusticl/core/memory.rs @@ -1831,12 +1831,24 @@ impl Image { } // If image is created from a buffer, use clear_image_buffer instead - if self.is_parent_buffer() { + if let Some(Mem::Buffer(parent)) = self.parent() { let strides = ( self.image_desc.row_pitch()? as usize, self.image_desc.slice_pitch(), ); - ctx.clear_image_buffer(res, &new_pattern, origin, region, strides, pixel_size); + let offset = parent.apply_offset(CLVec::calc_offset( + origin, + [pixel_size, strides.0, strides.1], + ))?; + + ctx.clear_image_buffer( + res, + &new_pattern, + offset.try_into_with_err(CL_OUT_OF_HOST_MEMORY)?, + region, + strides, + pixel_size, + ); } else { let bx = create_pipe_box(*origin, *region, self.mem_type)?; ctx.clear_texture(res, &new_pattern, &bx); @@ -1851,10 +1863,6 @@ impl Image { matches!(entry, Entry::Occupied(entry) if entry.get().count > 0) } - pub fn is_parent_buffer(&self) -> bool { - matches!(self.parent(), Some(Mem::Buffer(_))) - } - pub fn map( &self, origin: CLVec, @@ -2116,12 +2124,23 @@ impl Image { pub fn sampler_view<'c>(&self, ctx: &'c QueueContext) -> CLResult> { let res = self.get_res_for_access(ctx, RWFlags::RD)?; - let template = if res.is_buffer() && self.mem_type == CL_MEM_OBJECT_IMAGE2D { - res.pipe_sampler_view_template_2d_buffer(self.pipe_format, &self.buffer_2d_info()?) + let template = if let Some(Mem::Buffer(parent)) = self.parent() { + if self.mem_type == CL_MEM_OBJECT_IMAGE2D { + res.pipe_sampler_view_template_2d_buffer( + self.pipe_format, + &self.buffer_2d_info()?, + parent.offset() as u32 / self.image_format.pixel_size().unwrap() as u32, + ) + } else { + assert_eq!(self.mem_type, CL_MEM_OBJECT_IMAGE1D_BUFFER); + // we need to pass in the size of the buffer, not the width. + let size = self.size.try_into_with_err(CL_OUT_OF_RESOURCES)?; + let offset = parent.offset().try_into_with_err(CL_OUT_OF_RESOURCES)?; + res.pipe_sampler_view_template_1d_buffer(self.pipe_format, size, offset) + } } else if res.is_buffer() { - // we need to pass in the size of the buffer, not the width. let size = self.size.try_into_with_err(CL_OUT_OF_RESOURCES)?; - res.pipe_sampler_view_template_1d_buffer(self.pipe_format, size) + res.pipe_sampler_view_template_1d_buffer(self.pipe_format, size, 0) } else { res.pipe_sampler_view_template() }; @@ -2133,17 +2152,23 @@ impl Image { let rw = if read_write { RWFlags::RW } else { RWFlags::WR }; let res = self.get_res_for_access(ctx, rw)?; - if res.is_buffer() && self.mem_type == CL_MEM_OBJECT_IMAGE2D { - Ok( - res.pipe_image_view_2d_buffer( + if let Some(Mem::Buffer(parent)) = self.parent() { + if self.mem_type == CL_MEM_OBJECT_IMAGE2D { + Ok(res.pipe_image_view_2d_buffer( self.pipe_format, read_write, &self.buffer_2d_info()?, - ), - ) + parent.offset() as u32 / self.image_format.pixel_size().unwrap() as u32, + )) + } else { + assert_eq!(self.mem_type, CL_MEM_OBJECT_IMAGE1D_BUFFER); + let size = self.size.try_into_with_err(CL_OUT_OF_RESOURCES)?; + let offset = parent.offset().try_into_with_err(CL_OUT_OF_RESOURCES)?; + Ok(res.pipe_image_view_1d_buffer(self.pipe_format, read_write, size, offset)) + } } else if res.is_buffer() { let size = self.size.try_into_with_err(CL_OUT_OF_RESOURCES)?; - Ok(res.pipe_image_view_1d_buffer(self.pipe_format, read_write, size)) + Ok(res.pipe_image_view_1d_buffer(self.pipe_format, read_write, size, 0)) } else { Ok(res.pipe_image_view(read_write)) } diff --git a/src/gallium/frontends/rusticl/mesa/pipe/context.rs b/src/gallium/frontends/rusticl/mesa/pipe/context.rs index 369101d079c..083fca34215 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe/context.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe/context.rs @@ -135,7 +135,7 @@ impl PipeContext { &self, res: &PipeResource, pattern: &[u32], - origin: &[usize; 3], + offset_bytes: u32, region: &[usize; 3], strides: (usize, usize), pixel_size: usize, @@ -144,16 +144,14 @@ impl PipeContext { for z in 0..region[2] { for y in 0..region[1] { let pitch = [pixel_size, row_pitch, slice_pitch]; - // Convoluted way of doing (origin + [0, y, z]) * pitch - let offset = (0..3) - .map(|i| ((origin[i] + [0, y, z][i]) * pitch[i]) as u32) - .sum(); + // Convoluted way of doing [0, y, z] * pitch + let offset: u32 = (0..3).map(|i| ([0, y, z][i] * pitch[i]) as u32).sum(); unsafe { self.pipe.as_ref().clear_buffer.unwrap()( self.pipe.as_ptr(), res.pipe(), - offset, + offset + offset_bytes, (region[0] * pixel_size) as u32, pattern.as_ptr().cast(), pixel_size as i32, diff --git a/src/gallium/frontends/rusticl/mesa/pipe/resource.rs b/src/gallium/frontends/rusticl/mesa/pipe/resource.rs index 21da085068e..06e518cb466 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe/resource.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe/resource.rs @@ -166,6 +166,7 @@ impl PipeResource { format: pipe_format, read_write: bool, size: u32, + offset_bytes: u32, ) -> PipeImageView { debug_assert!(self.is_buffer()); @@ -182,7 +183,7 @@ impl PipeResource { shader_access: shader_access, u: pipe_image_view__bindgen_ty_1 { buf: pipe_image_view__bindgen_ty_1__bindgen_ty_2 { - offset: 0, + offset: offset_bytes, size: size, }, }, @@ -194,6 +195,7 @@ impl PipeResource { format: pipe_format, read_write: bool, app_img_info: &AppImgInfo, + offset_pixels: u32, ) -> PipeImageView { debug_assert!(self.is_buffer()); @@ -210,7 +212,7 @@ impl PipeResource { shader_access: shader_access, u: pipe_image_view__bindgen_ty_1 { tex2d_from_buf: pipe_tex2d_from_buf { - offset: 0, + offset: offset_pixels, row_stride: app_img_info.row_stride as u16, width: app_img_info.width as u16, height: app_img_info.height as u16, @@ -234,6 +236,7 @@ impl PipeResource { &self, format: pipe_format, size: u32, + offset_bytes: u32, ) -> pipe_sampler_view { debug_assert!(self.is_buffer()); @@ -245,7 +248,7 @@ impl PipeResource { // write the entire union field because u_sampler_view_default_template might have left it // in an undefined state. res.u.buf = pipe_sampler_view__bindgen_ty_1__bindgen_ty_2 { - offset: 0, + offset: offset_bytes, size: size, }; @@ -256,6 +259,7 @@ impl PipeResource { &self, format: pipe_format, app_img_info: &AppImgInfo, + offset_pixels: u32, ) -> pipe_sampler_view { debug_assert!(self.is_buffer()); @@ -267,7 +271,7 @@ impl PipeResource { // write the entire union field because u_sampler_view_default_template might have left it // in an undefined state. res.u.tex2d_from_buf = pipe_tex2d_from_buf { - offset: 0, + offset: offset_pixels, row_stride: app_img_info.row_stride as u16, width: app_img_info.width as u16, height: app_img_info.height as u16,