rusticl/mem: split Image::copy_to into Buffer and Image versions

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27376>
This commit is contained in:
Karol Herbst
2024-01-30 13:38:14 +01:00
committed by Marge Bot
parent c0c6eca095
commit 2db23aa207
2 changed files with 87 additions and 41 deletions
+2 -3
View File
@@ -1880,7 +1880,7 @@ fn enqueue_copy_image(
event,
false,
Box::new(move |q, ctx| {
src_image.copy_to(q, ctx, &dst_image, src_origin, dst_origin, &region)
src_image.copy_to_image(q, ctx, &dst_image, src_origin, dst_origin, &region)
}),
)
@@ -2027,7 +2027,6 @@ fn enqueue_copy_image_to_buffer(
let region = unsafe { CLVec::from_raw(region) };
let src_origin = unsafe { CLVec::from_raw(src_origin) };
let dst_origin = CLVec::new([dst_offset, 0, 0]);
// CL_INVALID_VALUE if values in src_origin and region do not follow rules described in the
// argument description for src_origin and region.
@@ -2042,7 +2041,7 @@ fn enqueue_copy_image_to_buffer(
evs,
event,
false,
Box::new(move |q, ctx| src.copy_to(q, ctx, &dst, src_origin, dst_origin, &region)),
Box::new(move |q, ctx| src.copy_to_buffer(q, ctx, &dst, src_origin, dst_offset, &region)),
)
//• CL_INVALID_MEM_OBJECT if src_image is not a valid image object or dst_buffer is not a valid buffer object or if src_image is a 1D image buffer object created from dst_buffer.
+85 -38
View File
@@ -779,10 +779,6 @@ impl MemBase {
matches!(self.parent, Some(Mem::Buffer(_)))
}
pub fn is_image_from_buffer(&self) -> bool {
self.is_parent_buffer() && self.mem_type == CL_MEM_OBJECT_IMAGE2D
}
// this is kinda bogus, because that won't work with system SVM, but the spec wants us to
// implement this.
pub fn is_svm(&self) -> bool {
@@ -1216,44 +1212,98 @@ impl Buffer {
}
impl Image {
pub fn copy_to(
pub fn copy_to_buffer(
&self,
q: &Queue,
ctx: &PipeContext,
dst: &MemBase,
mut src_origin: CLVec<usize>,
mut dst_origin: CLVec<usize>,
dst: &Buffer,
src_origin: CLVec<usize>,
dst_offset: usize,
region: &CLVec<usize>,
) -> CLResult<()> {
let src_parent = self.to_parent(&mut src_origin[0]);
let dst_parent = dst.to_parent(&mut dst_origin[0]);
let dst_offset = dst.apply_offset(dst_offset)?;
let bpp = self.pixel_size().unwrap().into();
let src_pitch;
let tx_src;
if self.is_parent_buffer() {
src_pitch = [
bpp,
self.image_desc.row_pitch()? as usize,
self.image_desc.slice_pitch(),
];
let (offset, size) = CLVec::calc_offset_size(src_origin, region, src_pitch);
tx_src = self.tx(q, ctx, offset, size, RWFlags::RD)?;
} else {
tx_src = self.tx_image(
q,
ctx,
&create_pipe_box(src_origin, *region, self.mem_type)?,
RWFlags::RD,
)?;
src_pitch = [1, tx_src.row_pitch() as usize, tx_src.slice_pitch()];
}
// If image is created from a buffer, use image's slice and row pitch instead
let dst_pitch = [bpp, bpp * region[0], bpp * region[0] * region[1]];
let dst_origin: CLVec<usize> = [dst_offset, 0, 0].into();
let (offset, size) = CLVec::calc_offset_size(dst_origin, region, dst_pitch);
let tx_dst = dst.tx(q, ctx, offset, size, RWFlags::WR)?;
// Those pitch values cannot have 0 value in its coordinates
debug_assert!(src_pitch[0] != 0 && src_pitch[1] != 0 && src_pitch[2] != 0);
debug_assert!(dst_pitch[0] != 0 && dst_pitch[1] != 0 && dst_pitch[2] != 0);
sw_copy(
tx_src.ptr(),
tx_dst.ptr(),
region,
&CLVec::default(),
src_pitch[1],
src_pitch[2],
&CLVec::default(),
dst_pitch[1],
dst_pitch[2],
bpp as u8,
);
Ok(())
}
pub fn copy_to_image(
&self,
q: &Queue,
ctx: &PipeContext,
dst: &Image,
src_origin: CLVec<usize>,
dst_origin: CLVec<usize>,
region: &CLVec<usize>,
) -> CLResult<()> {
let src_parent = self.get_parent();
let dst_parent = dst.get_parent();
let src_res = src_parent.get_res_of_dev(q.device)?;
let dst_res = dst_parent.get_res_of_dev(q.device)?;
// We just want to use sw_copy if mem objects have different types
// or if copy can have custom strides (image2d from buff/images)
if dst.is_buffer() || self.parent.is_some() || !dst.is_buffer() && dst.parent.is_some() {
// We just want to use sw_copy if mem objects have different types or if copy can have
// custom strides (image2d from buff/images)
if src_parent.is_buffer() || dst_parent.is_buffer() {
let bpp = self.pixel_size().unwrap().into();
let tx_src;
let tx_dst;
let mut src_pitch = [0, 0, 0];
let mut dst_pitch = [0, 0, 0];
let bpp = self.pixel_size().unwrap().into();
let dst_pitch;
let src_pitch;
if src_parent.is_buffer() {
// If image is created from a buffer, use image's slice and row pitch instead
src_pitch[0] = bpp;
if self.is_image_from_buffer() {
src_pitch[1] = self.image_desc.row_pitch()? as usize;
src_pitch[2] = self.image_desc.slice_pitch();
} else {
src_pitch[1] = region[0] * bpp;
src_pitch[2] = region[0] * region[1] * bpp;
}
src_pitch = [
bpp,
self.image_desc.row_pitch()? as usize,
self.image_desc.slice_pitch(),
];
let (offset, size) = CLVec::calc_offset_size(src_origin, region, src_pitch);
tx_src = src_parent.tx(q, ctx, offset, size, RWFlags::RD)?;
tx_src = self.tx(q, ctx, offset, size, RWFlags::RD)?;
} else {
tx_src = src_parent.tx_image(
tx_src = self.tx_image(
q,
ctx,
&create_pipe_box(src_origin, *region, src_parent.mem_type)?,
@@ -1265,19 +1315,16 @@ impl Image {
if dst_parent.is_buffer() {
// If image is created from a buffer, use image's slice and row pitch instead
dst_pitch[0] = bpp;
if dst.is_image_from_buffer() {
dst_pitch[1] = dst.image_desc.row_pitch()? as usize;
dst_pitch[2] = dst.image_desc.slice_pitch();
} else {
dst_pitch[1] = region[0] * bpp;
dst_pitch[2] = region[0] * region[1] * bpp;
}
dst_pitch = [
bpp,
dst.image_desc.row_pitch()? as usize,
dst.image_desc.slice_pitch(),
];
let (offset, size) = CLVec::calc_offset_size(dst_origin, region, dst_pitch);
tx_dst = dst_parent.tx(q, ctx, offset, size, RWFlags::WR)?;
tx_dst = dst.tx(q, ctx, offset, size, RWFlags::WR)?;
} else {
tx_dst = dst_parent.tx_image(
tx_dst = dst.tx_image(
q,
ctx,
&create_pipe_box(dst_origin, *region, dst_parent.mem_type)?,