|
1 |
| -use bytemuck::{Pod, Zeroable}; |
| 1 | +use core::mem::offset_of; |
2 | 2 | use spirv_std::glam::*;
|
| 3 | +use experiments::*; |
3 | 4 |
|
4 |
| -#[repr(C)] |
5 |
| -#[derive(Copy, Clone, Zeroable, Pod)] |
6 |
| -pub struct SizeAndAlign { |
7 |
| - pub size: u32, |
8 |
| - pub align: u32, |
| 5 | +pub struct BumpAlloc(usize); |
| 6 | + |
| 7 | +impl BumpAlloc { |
| 8 | + pub fn inc(&mut self) -> usize { |
| 9 | + let old = self.0; |
| 10 | + self.0 += 1; |
| 11 | + old |
| 12 | + } |
| 13 | +} |
| 14 | + |
| 15 | +pub trait WriteLayout { |
| 16 | + fn write_layout(offset: &mut BumpAlloc, out: &mut [u32]); |
9 | 17 | }
|
10 | 18 |
|
11 |
| -impl SizeAndAlign { |
12 |
| - pub fn from<T>() -> Self { |
13 |
| - Self { |
14 |
| - size: size_of::<T>() as u32, |
15 |
| - align: align_of::<T>() as u32, |
| 19 | +macro_rules! write_layout { |
| 20 | + ($out:ident, $offset:ident, $name:ident($($member:ident),*)) => { |
| 21 | + { |
| 22 | + // offset 0: size |
| 23 | + $out[$offset.inc()] = size_of::<$name>() as u32; |
| 24 | + // offset 4: alignment |
| 25 | + $out[$offset.inc()] = align_of::<$name>() as u32; |
| 26 | + // offset 8 onwards: members |
| 27 | + $($out[$offset.inc()] = offset_of!($name, $member) as u32;)* |
16 | 28 | }
|
17 |
| - } |
| 29 | + }; |
| 30 | +} |
18 | 31 |
|
19 |
| - pub fn flatten(&self) -> [u32; 2] { |
20 |
| - [self.size, self.align] |
21 |
| - } |
| 32 | +/// gid is checked between `0..LAYOUT_COUNT` |
| 33 | +pub const LAYOUT_COUNT: usize = 0x40; |
| 34 | +/// at byte offset 0x100 * N starts layout N |
| 35 | +pub const LAYOUT_MAX_SIZE: usize = 0x100 / 0x4; |
| 36 | +pub const LAYOUT_LEN: usize = LAYOUT_COUNT * LAYOUT_MAX_SIZE; |
| 37 | + |
| 38 | +pub fn eval_layouts(gid: u32, out: &mut [u32]) { |
| 39 | + let mut offset = BumpAlloc(gid as usize * LAYOUT_MAX_SIZE); |
| 40 | + match gid { |
| 41 | + // vec |
| 42 | + 0x0 => write_layout!(out, offset, u32()), |
| 43 | + 0x1 => write_layout!(out, offset, UVec2(x, y)), |
| 44 | + 0x2 => write_layout!(out, offset, UVec3(x, y, z)), |
| 45 | + 0x3 => write_layout!(out, offset, UVec4(x, y, z, w)), |
| 46 | + 0x4 => write_layout!(out, offset, i32()), |
| 47 | + 0x5 => write_layout!(out, offset, IVec2(x, y)), |
| 48 | + 0x6 => write_layout!(out, offset, IVec3(x, y, z)), |
| 49 | + 0x7 => write_layout!(out, offset, IVec4(x, y, z, w)), |
| 50 | + 0x8 => write_layout!(out, offset, f32()), |
| 51 | + 0x9 => write_layout!(out, offset, Vec2(x, y)), |
| 52 | + 0xA => write_layout!(out, offset, Vec3(x, y, z)), |
| 53 | + 0xB => write_layout!(out, offset, Vec4()), // private members |
| 54 | + 0xC => write_layout!(out, offset, Vec3A()), // private members |
| 55 | + |
| 56 | + // experiments structs |
| 57 | + 0x10 => write_layout!(out, offset, Struct0x10(a, b)), |
| 58 | + 0x11 => write_layout!(out, offset, Struct0x11(a, b)), |
| 59 | + _ => {} |
| 60 | + } |
22 | 61 | }
|
23 | 62 |
|
24 |
| -pub type EvalResult = [SizeAndAlign; 8]; |
25 |
| - |
26 |
| -pub fn eval_layouts() -> EvalResult { |
27 |
| - [ |
28 |
| - SizeAndAlign::from::<u32>(), |
29 |
| - SizeAndAlign::from::<UVec2>(), |
30 |
| - SizeAndAlign::from::<UVec3>(), |
31 |
| - SizeAndAlign::from::<UVec4>(), |
32 |
| - SizeAndAlign::from::<f32>(), |
33 |
| - SizeAndAlign::from::<Vec2>(), |
34 |
| - SizeAndAlign::from::<Vec3>(), |
35 |
| - SizeAndAlign::from::<Vec4>(), |
36 |
| - ] |
| 63 | +mod experiments { |
| 64 | + use spirv_std::glam::*; |
| 65 | + |
| 66 | + #[repr(C)] |
| 67 | + pub struct Struct0x10 { |
| 68 | + pub a: f32, |
| 69 | + /// if UVec2 has an alignment of |
| 70 | + /// * 4 (CPU): 12 size, 4 alignment, 4 b offset |
| 71 | + /// * 8 (GPU): 16 size, 8 alignment, 8 b offset |
| 72 | + pub b: UVec2, |
| 73 | + } |
| 74 | + |
| 75 | + #[repr(C)] |
| 76 | + pub struct Struct0x11 { |
| 77 | + pub a: Vec3, |
| 78 | + /// if Vec3 has an alignment of |
| 79 | + /// * 4 (CPU): 16 size, 4 alignment, 12 b offset |
| 80 | + /// * 16 (GPU): 32 size, 16 alignment, 16 b offset |
| 81 | + pub b: f32, |
| 82 | + } |
37 | 83 | }
|
0 commit comments