rusticl: Enabling image fill for images created from buffers

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20378>
This commit is contained in:
Antonio Gomes
2022-12-06 18:39:59 -03:00
committed by Marge Bot
parent e40fd3bd60
commit 3c51db3f21
2 changed files with 49 additions and 4 deletions
+14 -4
View File
@@ -762,12 +762,11 @@ impl Mem {
assert!(!self.is_buffer());
let res = self.get_res()?.get(&q.device).unwrap();
let bx = create_box(origin, region, self.mem_type)?;
// 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.pixel_size().unwrap() as usize, size_of::<u32>());
let mut new_pattern: Vec<u32> = vec![0; size / size_of::<u32>()];
let pixel_size = align(self.pixel_size().unwrap() as usize, size_of::<u32>());
let mut new_pattern: Vec<u32> = vec![0; pixel_size / size_of::<u32>()];
// we don't support CL_DEPTH for now
assert!(pattern.len() == 4);
@@ -787,7 +786,18 @@ impl Mem {
);
}
ctx.clear_texture(res, &new_pattern, &bx);
// If image is created from a buffer, use clear_image_buffer instead
// for each row
if self.is_parent_buffer() {
let strides = (
self.image_desc.row_pitch()? as usize,
self.image_desc.slice_pitch()? as usize,
);
ctx.clear_image_buffer(res, &new_pattern, origin, region, strides, pixel_size);
} else {
let bx = create_box(origin, region, self.mem_type)?;
ctx.clear_texture(res, &new_pattern, &bx);
}
Ok(())
}
@@ -123,6 +123,41 @@ impl PipeContext {
}
}
pub fn clear_image_buffer(
&self,
res: &PipeResource,
pattern: &[u32],
origin: &[usize; 3],
region: &[usize; 3],
strides: (usize, usize),
pixel_size: usize,
) {
let (row_pitch, slice_pitch) = strides;
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();
// SAFETY: clear_buffer arguments are specified
// in bytes, so pattern.len() dimension value
// should be multiplied by pixel_size
unsafe {
self.pipe.as_ref().clear_buffer.unwrap()(
self.pipe.as_ptr(),
res.pipe(),
offset,
(region[0] * pixel_size) as u32,
pattern.as_ptr().cast(),
(pattern.len() * pixel_size) as i32,
)
};
}
}
}
pub fn clear_texture(&self, res: &PipeResource, pattern: &[u32], bx: &pipe_box) {
unsafe {
self.pipe.as_ref().clear_texture.unwrap()(