1#![allow(clippy::assertions_on_constants)]
16
17use std::mem;
18
19use crate::cpu::PixelSegment;
20
21pub(crate) const PIXEL_WIDTH: usize = 16;
22pub(crate) const PIXEL_DOUBLE_WIDTH: usize = PIXEL_WIDTH * 2;
23pub(crate) const PIXEL_SHIFT: usize = PIXEL_WIDTH.trailing_zeros() as usize;
24
25pub const MAX_WIDTH: usize = 1 << 16;
26pub const MAX_HEIGHT: usize = 1 << 15;
27
28pub(crate) const MAX_WIDTH_SHIFT: usize = MAX_WIDTH.trailing_zeros() as usize;
29pub(crate) const MAX_HEIGHT_SHIFT: usize = MAX_HEIGHT.trailing_zeros() as usize;
30
31pub mod cpu {
32 pub const TILE_WIDTH: usize = 16;
33 const _: () = assert!(TILE_WIDTH % 16 == 0);
34 const _: () = assert!(TILE_WIDTH <= 128);
35
36 pub(crate) const TILE_WIDTH_SHIFT: usize = TILE_WIDTH.trailing_zeros() as usize;
37
38 pub const TILE_HEIGHT: usize = 16;
39 const _: () = assert!(TILE_HEIGHT % 16 == 0);
40 const _: () = assert!(TILE_HEIGHT <= 128);
41
42 pub(crate) const TILE_HEIGHT_SHIFT: usize = TILE_HEIGHT.trailing_zeros() as usize;
43}
44
45pub mod gpu {
46 pub const TILE_WIDTH: usize = 16;
47 pub const TILE_HEIGHT: usize = 4;
48}
49
50#[derive(Clone, Copy, Debug)]
51pub(crate) enum BitField {
52 TileY,
53 TileX,
54 LayerId,
55 LocalX,
56 LocalY,
57 DoubleAreaMultiplier,
58 Cover,
59}
60
61#[derive(Debug)]
62pub(crate) struct BitFieldMap {
63 lengths: [usize; 7],
64}
65
66impl BitFieldMap {
67 #[inline]
68 pub const fn new<const TW: usize, const TH: usize>() -> Self {
69 let tile_width_shift = TW.trailing_zeros() as usize;
70 let tile_height_shift = TH.trailing_zeros() as usize;
71
72 let mut lengths = [
73 MAX_HEIGHT_SHIFT - tile_height_shift,
74 MAX_WIDTH_SHIFT - tile_width_shift,
75 0,
76 tile_width_shift,
77 tile_height_shift,
78 ((PIXEL_WIDTH + 1) * 2).next_power_of_two().trailing_zeros() as usize,
79 ((PIXEL_WIDTH + 1) * 2).next_power_of_two().trailing_zeros() as usize,
80 ];
81
82 let layer_id_len = mem::size_of::<PixelSegment<TW, TH>>() * 8
83 - lengths[BitField::TileY as usize]
84 - lengths[BitField::TileX as usize]
85 - lengths[BitField::LocalX as usize]
86 - lengths[BitField::LocalY as usize]
87 - lengths[BitField::DoubleAreaMultiplier as usize]
88 - lengths[BitField::Cover as usize];
89
90 lengths[BitField::LayerId as usize] = layer_id_len;
91
92 Self { lengths }
93 }
94
95 #[inline]
96 pub const fn get(&self, bit_field: BitField) -> usize {
97 self.lengths[bit_field as usize]
98 }
99
100 #[inline]
101 pub const fn get_by_index(&self, i: usize) -> usize {
102 self.lengths[i]
103 }
104}
105
106pub const LAYER_LIMIT: usize = (1
107 << BitFieldMap::new::<{ cpu::TILE_WIDTH }, { cpu::TILE_HEIGHT }>().get(BitField::LayerId))
108 - 1;
109const _: () = assert!(
110 LAYER_LIMIT
111 == (1
112 << BitFieldMap::new::<{ gpu::TILE_WIDTH }, { gpu::TILE_HEIGHT }>()
113 .get(BitField::LayerId))
114 - 1,
115 "LAYER_LIMIT must be the same both on cpu and gpu",
116);