Skip to content

Commit

Permalink
better accessor support
Browse files Browse the repository at this point in the history
  • Loading branch information
schell committed Dec 3, 2023
1 parent 75f7cd0 commit ddf06a3
Show file tree
Hide file tree
Showing 5 changed files with 342 additions and 126 deletions.
63 changes: 63 additions & 0 deletions crates/renderling-shader/src/bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,66 @@ pub fn insert(bits: &mut u32, (shift, mask): (u32, u32), value: u32) {
pub fn extract(bits: u32, (shift, mask): (u32, u32)) -> u32 {
(bits >> shift) & mask
}

/// The shift/mask range for the first 8 bits of a u32.
pub const U8_0_BITS: (u32, u32) = bits(0..=7);
/// The shift/mask range for the second 8 bits of a u32.
pub const U8_1_BITS: (u32, u32) = bits(8..=15);
/// The shift/mask range for the third 8 bits of a u32.
pub const U8_2_BITS: (u32, u32) = bits(16..=23);
/// The shift/mask range for the fourth 8 bits of a u32.
pub const U8_3_BITS: (u32, u32) = bits(24..=31);

/// The shift/mask range for the first 16 bits of a u32.
pub const U16_0_BITS: (u32, u32) = bits(0..=15);
/// The shift/mask range for the second 16 bits of a u32.
pub const U16_1_BITS: (u32, u32) = bits(16..=31);

#[cfg(test)]
mod test {
use super::*;

#[test]
fn bits_sanity() {
let mut store = 0;
assert_eq!(
"00000000000000000000000000000000",
&format!("{:032b}", store)
);
insert(&mut store, bits(0..=7), u8::MAX as u32);
assert_eq!(
"00000000000000000000000011111111",
&format!("{:032b}", store)
);
store = 0;
insert(&mut store, bits(8..=15), u8::MAX as u32);
assert_eq!(
"00000000000000001111111100000000",
&format!("{:032b}", store)
);
}

#[test]
fn bits_u8_sanity() {
let mut bits = 0;
println!("bits: {:032b}", bits);
super::insert(&mut bits, super::U8_0_BITS, 6u8 as u32);
println!("bits: {:032b}", bits);
assert_eq!(super::extract(bits, super::U8_0_BITS), 6);
super::insert(&mut bits, super::U8_1_BITS, 5u8 as u32);
println!("bits: {:032b}", bits);
assert_eq!(super::extract(bits, super::U8_0_BITS), 6);
assert_eq!(super::extract(bits, super::U8_1_BITS), 5);
super::insert(&mut bits, super::U8_2_BITS, 4u8 as u32);
println!("bits: {:032b}", bits);
assert_eq!(super::extract(bits, super::U8_0_BITS), 6);
assert_eq!(super::extract(bits, super::U8_1_BITS), 5);
assert_eq!(super::extract(bits, super::U8_2_BITS), 4);
super::insert(&mut bits, super::U8_3_BITS, 3u8 as u32);
println!("bits: {:032b}", bits);
assert_eq!(super::extract(bits, super::U8_0_BITS), 6);
assert_eq!(super::extract(bits, super::U8_1_BITS), 5);
assert_eq!(super::extract(bits, super::U8_2_BITS), 4);
assert_eq!(super::extract(bits, super::U8_3_BITS), 3);
}
}
58 changes: 52 additions & 6 deletions crates/renderling-shader/src/gltf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
pub struct GltfBuffer(pub Array<u32>);

#[repr(u32)]
#[derive(Default, Clone, Copy)]
#[derive(Default, Clone, Copy, PartialEq, Debug)]
pub enum DataType {
I8,
U8,
Expand Down Expand Up @@ -102,9 +102,27 @@ impl Slabbed for Dimensions {
}
}

/// Reads a u8 from the slab at the given **byte** offset.
fn get_u8_at_offset(offset: usize, slab: &[u32]) -> u8 {
let u32_offset = offset / 4;
let mut u32 = 0u32;
let _ = u32.read_slab(u32_offset, slab);
let byte_offset = offset % 4;
match byte_offset {
0 => u32.to_le_bytes()[0],
1 => u32.to_le_bytes()[1],
2 => u32.to_le_bytes()[2],
3 => u32.to_le_bytes()[3],
_ => 0, // unreachable
}
}

#[derive(Default, Clone, Copy, Slabbed)]
pub struct GltfAccessor {
// The byte size of each component that this accessor describes.
// The byte size of each element that this accessor describes.
//
/// For example, if the accessor describes a `Vec3` of F32s, then
// the size is 3 * 4 = 12.
pub size: u32,
pub buffer: Id<GltfBuffer>,
// Returns the offset relative to the start of the parent buffer view in bytes.
Expand All @@ -117,14 +135,42 @@ pub struct GltfAccessor {
// number of bytes in the buffer view.
pub count: u32,
// The data type of components in the attribute.
pub component_type: DataType,
pub data_type: DataType,
// Specifies if the attribute is a scalar, vector, or matrix.
pub dimensions: Dimensions,
// Whether or not the attribute is normalized.
pub normalized: bool,
}

impl GltfAccessor {
/// Retreive the nth element.
pub fn get1(&self, index: usize, slab: &[u32]) -> u32 {
let buffer = slab.read(self.buffer);
let buffer_start = buffer.0.at(0);
let byte_offset =
buffer_start.index() * 4 + self.view_offset as usize + index * self.size as usize;
let u32_offset = byte_offset / 4;
let mut t = 0u32;
t.read_slab(u32_offset, slab);
let byte_mod = byte_offset as u32 % 4;
let mask = match self.data_type {
DataType::I8 => 0xF,
DataType::U8 => 0xF,
DataType::I16 => 0xFF,
DataType::U16 => 0xFF,
DataType::U32 => 0xFFFF,
DataType::F32 => 0xFFFF,
};
let shift = match byte_mod {
0 => 0,
1 => 8,
2 => 16,
3 => 24,
_ => 0, // unreachable
};
crate::bits::extract(t, (shift, mask))
}

pub fn get_scalar_u32(&self, index: usize, slab: &[u32]) -> u32 {
let byte_offset = self.view_offset + index as u32 * self.view_stride;
let u32_offset = byte_offset / 4;
Expand Down Expand Up @@ -178,13 +224,13 @@ pub struct GltfPrimitive {
}

impl GltfPrimitive {
pub fn get_vertex(&self, index: usize, slab: &[u32]) -> crate::stage::Vertex {
pub fn get_vertex(&self, vertex_index: usize, slab: &[u32]) -> crate::stage::Vertex {
let index = if self.indices.is_some() {
let indices = slab.read(self.indices);
let index = indices.get_scalar_u32(index, slab);
let index = indices.get1(vertex_index, slab);
index as usize
} else {
index
vertex_index
};
let positions = slab.read(self.positions);
let position = positions.get_vec4(index, slab);
Expand Down
Binary file modified crates/renderling/src/linkage/stage-new_stage_vertex.spv
Binary file not shown.
Binary file modified crates/renderling/src/linkage/tutorial-slabbed_render_unit.spv
Binary file not shown.
Loading

0 comments on commit ddf06a3

Please sign in to comment.