region: &CLVec<usize>,
row_pitch: usize,
slice_pitch: usize,
+ pixel_size: usize,
) -> (usize, usize) {
- let pitch = [1, row_pitch, slice_pitch];
+ let pitch = [pixel_size, row_pitch, slice_pitch];
(*origin * pitch, *region * pitch)
}
}))
}
+ pub fn pixel_size(&self) -> Option<u8> {
+ if self.is_buffer() {
+ Some(1)
+ } else {
+ self.image_format.pixel_size()
+ }
+ }
+
pub fn is_buffer(&self) -> bool {
self.mem_type == CL_MEM_OBJECT_BUFFER
}
let b = self.to_parent(&mut offset);
let r = b.get_res()?.get(&q.device).unwrap();
- assert!(self.is_buffer());
-
Ok(ctx.buffer_map(
r,
offset.try_into().map_err(|_| CL_OUT_OF_HOST_MEMORY)?,
ptr::eq(a, b)
}
+ pub fn is_parent_buffer(&self) -> bool {
+ self.parent.as_ref().map_or(false, |p| p.is_buffer())
+ }
+
+ pub fn is_image_from_buffer(&self) -> bool {
+ self.is_parent_buffer() && self.mem_type == CL_MEM_OBJECT_IMAGE2D
+ }
+
fn get_res(&self) -> CLResult<&HashMap<Arc<Device>, Arc<PipeResource>>> {
self.parent
.as_ref()
let tx_dst;
if self.is_buffer() {
- let bpp = dst.image_format.pixel_size().unwrap() as usize;
+ let bpp = dst.pixel_size().unwrap() as usize;
tx_src = self.tx(q, ctx, src_origin[0], region.pixels() * bpp, RWFlags::RD)?;
tx_dst = dst.tx_image(
q,
bpp as u8,
)
} else {
- let bpp = self.image_format.pixel_size().unwrap() as usize;
+ let bpp = self.pixel_size().unwrap() as usize;
tx_src = self.tx_image(
q,
ctx,
// 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.image_format.pixel_size().unwrap() as usize,
- size_of::<u32>(),
- );
+ let size = align(self.pixel_size().unwrap() as usize, size_of::<u32>());
let mut new_pattern: Vec<u32> = vec![0; size / size_of::<u32>()];
// we don't support CL_DEPTH for now
dst_row_pitch: usize,
dst_slice_pitch: usize,
) -> CLResult<()> {
- if self.is_buffer() {
- let (offset, size) =
- buffer_offset_size(dst_origin, region, dst_row_pitch, dst_slice_pitch);
+ if self.is_buffer() || self.is_image_from_buffer() {
+ let pixel_size = self.pixel_size().unwrap();
+ let (offset, size) = buffer_offset_size(
+ dst_origin,
+ region,
+ dst_row_pitch,
+ dst_slice_pitch,
+ pixel_size.try_into().unwrap(),
+ );
let tx = self.tx(q, ctx, offset, size, RWFlags::WR)?;
sw_copy(
&CLVec::default(),
dst_row_pitch,
dst_slice_pitch,
- 1,
+ pixel_size,
);
} else {
assert!(dst_row_pitch == self.image_desc.image_row_pitch);
let tx;
let pixel_size;
- if self.is_buffer() {
- let (offset, size) =
- buffer_offset_size(src_origin, region, src_row_pitch, src_slice_pitch);
+ if self.is_buffer() || self.is_image_from_buffer() {
+ pixel_size = self.pixel_size().unwrap();
+ let (offset, size) = buffer_offset_size(
+ src_origin,
+ region,
+ src_row_pitch,
+ src_slice_pitch,
+ pixel_size.try_into().unwrap(),
+ );
tx = self.tx(q, ctx, offset, size, RWFlags::RD)?;
- pixel_size = 1;
} else {
assert!(dst_origin == &CLVec::default());
src_row_pitch = tx.row_pitch() as usize;
src_slice_pitch = tx.slice_pitch() as usize;
- pixel_size = self.image_format.pixel_size().unwrap();
+ pixel_size = self.pixel_size().unwrap();
};
sw_copy(
assert!(self.is_buffer());
assert!(dst.is_buffer());
- let (offset, size) = buffer_offset_size(src_origin, region, src_row_pitch, src_slice_pitch);
+ let (offset, size) =
+ buffer_offset_size(src_origin, region, src_row_pitch, src_slice_pitch, 1);
let tx_src = self.tx(q, ctx, offset, size, RWFlags::RD)?;
- let (offset, size) = buffer_offset_size(dst_origin, region, dst_row_pitch, dst_slice_pitch);
+ let (offset, size) =
+ buffer_offset_size(dst_origin, region, dst_row_pitch, dst_slice_pitch, 1);
let tx_dst = dst.tx(q, ctx, offset, size, RWFlags::WR)?;
// TODO check to use hw accelerated paths (e.g. resource_copy_region or blits)
ptr.add(
*origin
* [
- self.image_format.pixel_size().unwrap() as usize,
+ self.pixel_size().unwrap() as usize,
*row_pitch,
*slice_pitch,
],