use crate::geometry::Geometry;
use crate::shape::Shape;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Layout {
sublanes: usize,
lanes: usize,
tile_len: usize,
tiles_per_row: usize,
}
impl Layout {
pub fn new(shape: &Shape, geom: &Geometry) -> Self {
Layout {
sublanes: geom.sublanes,
lanes: geom.lanes,
tile_len: geom.tile_len(),
tiles_per_row: shape.padded_cols / geom.lanes,
}
}
#[inline]
pub fn offset(&self, row: usize, col: usize) -> usize {
let tile_row = row / self.sublanes;
let tile_col = col / self.lanes;
let sub = row % self.sublanes;
let lane = col % self.lanes;
let tile_index = tile_row * self.tiles_per_row + tile_col;
tile_index * self.tile_len + sub * self.lanes + lane
}
#[inline]
pub fn coord(&self, offset: usize) -> (usize, usize) {
let tile_index = offset / self.tile_len;
let within = offset % self.tile_len;
let tile_row = tile_index / self.tiles_per_row;
let tile_col = tile_index % self.tiles_per_row;
let sub = within / self.lanes;
let lane = within % self.lanes;
let row = tile_row * self.sublanes + sub;
let col = tile_col * self.lanes + lane;
(row, col)
}
#[inline]
pub fn tile_base(&self, tile_row: usize, tile_col: usize) -> usize {
(tile_row * self.tiles_per_row + tile_col) * self.tile_len
}
#[inline]
pub fn tiles_per_row(&self) -> usize {
self.tiles_per_row
}
}