mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 21:30:09 +01:00
rusticl/image: fix sub-buffer images
There were two issues with the current implementation: - We didn't set the offset for sampler and image views - Image::fill didn't take the parents offset into account Cc: mesa-stable Reported-by: Rob Clark <rob.clark@oss.qualcomm.com> Tested-by: Rob Clark <rob.clark@oss.qualcomm.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35537>
This commit is contained in:
parent
17fbd0df51
commit
7e9ee2000a
3 changed files with 53 additions and 26 deletions
|
|
@ -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<usize>,
|
||||
|
|
@ -2116,12 +2124,23 @@ impl Image {
|
|||
pub fn sampler_view<'c>(&self, ctx: &'c QueueContext) -> CLResult<PipeSamplerView<'c, '_>> {
|
||||
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))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue