Skip to content

Commit 780d3d1

Browse files
committed
vec3: difftest with member offset checking
1 parent 70a0e68 commit 780d3d1

File tree

4 files changed

+90
-36
lines changed

4 files changed

+90
-36
lines changed
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
use crate::layout::{LAYOUT_COUNT, LAYOUT_LEN, eval_layouts};
12
use difftest::config::Config;
2-
use crate::layout::eval_layouts;
33

44
pub fn run() {
55
let config = Config::from_path(std::env::args().nth(1).unwrap()).unwrap();
6-
config.write_result(bytemuck::bytes_of(&eval_layouts())).unwrap()
6+
let mut out = vec![0; LAYOUT_LEN];
7+
for gid in 0..LAYOUT_COUNT {
8+
eval_layouts(gid as u32, &mut out);
9+
}
10+
config.write_result(&out).unwrap()
711
}
Lines changed: 74 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,83 @@
1-
use bytemuck::{Pod, Zeroable};
1+
use core::mem::offset_of;
22
use spirv_std::glam::*;
3+
use experiments::*;
34

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]);
917
}
1018

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;)*
1628
}
17-
}
29+
};
30+
}
1831

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+
}
2261
}
2362

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+
}
3783
}
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
use crate::layout::{EvalResult, eval_layouts};
1+
use crate::layout::eval_layouts;
2+
use spirv_std::glam::UVec3;
23
use spirv_std::spirv;
34

45
#[spirv(compute(threads(1)))]
5-
pub fn main_cs(#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] output: &mut EvalResult) {
6-
*output = eval_layouts();
6+
pub fn main_cs(
7+
#[spirv(workgroup_id)] gid: UVec3,
8+
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] output: &mut [u32],
9+
) {
10+
eval_layouts(gid.x, output);
711
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
use crate::layout::EvalResult;
1+
use crate::layout::{LAYOUT_COUNT, LAYOUT_LEN};
22
use difftest::config::Config;
33
use difftest::scaffold::compute::{BufferConfig, RustComputeShader, WgpuComputeTestMultiBuffer};
44

55
pub fn run() {
66
let config = Config::from_path(std::env::args().nth(1).unwrap()).unwrap();
77
let test = WgpuComputeTestMultiBuffer::new(
88
RustComputeShader::default(),
9-
[1, 1, 1],
10-
Vec::from(&[BufferConfig::writeback(size_of::<EvalResult>())]),
9+
[LAYOUT_COUNT as u32, 1, 1],
10+
Vec::from(&[BufferConfig::writeback(LAYOUT_LEN * size_of::<u32>())]),
1111
);
1212
test.run_test(&config).unwrap();
1313
}

0 commit comments

Comments
 (0)