Skip to content

Commit

Permalink
successfully rendering simple gltf files w/ the new gpu-driven gltf p…
Browse files Browse the repository at this point in the history
…ipeline
  • Loading branch information
schell committed Dec 6, 2023
1 parent 57579de commit 1d7d349
Show file tree
Hide file tree
Showing 9 changed files with 833 additions and 268 deletions.
240 changes: 185 additions & 55 deletions crates/renderling-shader/src/bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
use core::ops::RangeInclusive;

use crate::{id::Id, slab::Slab};

/// Statically define a shift/mask range as a literal range of bits.
pub const fn bits(range: RangeInclusive<u32>) -> (u32, u32) {
let mut start = *range.start();
Expand Down Expand Up @@ -49,70 +51,127 @@ 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);

/// Extract the "nth" 8 bits of the u32 at the given index in the slab.
/// Extract 8 bits of the u32 at the given index in the slab.
///
/// Returns the extracted value, the index of the next component and the index
/// of the next u32 in the slab.
pub fn extract_u8(
// component index, eg 0 for the first 8 bits, 1 for the second 8 bits, etc
n: u32,
// index of the u32 in the slab
u32_index: usize,
// eg 0 for the first 8 bits, 1 for the second 8 bits, etc
byte_offset: usize,
// slab of u32s
slab: &[u32],
) -> (u32, u32, usize) {
match n {
0 => (extract(slab[u32_index], U8_0_BITS), 1, u32_index),
1 => (extract(slab[u32_index], U8_1_BITS), 2, u32_index),
2 => (extract(slab[u32_index], U8_2_BITS), 3, u32_index),
_ => (extract(slab[u32_index], U8_3_BITS), 0, u32_index + 1),
}
) -> (u32, usize, usize) {
const SHIFT_MASKS: [((u32, u32), usize); 4] = [
(U8_0_BITS, 0),
(U8_1_BITS, 0),
(U8_2_BITS, 0),
(U8_3_BITS, 1),
];
let byte_mod = byte_offset % 4;
let (shift_mask, index_inc) = SHIFT_MASKS[byte_mod as usize];
let u32_value = slab.read(Id::from(u32_index));
let value = extract(u32_value, shift_mask);
(value, u32_index + index_inc as usize, byte_mod + 1)
}

/// Extract the "nth" 8 bits of the u32 at the given index in the slab.
/// Extract 8 bits of the u32 at the given index in the slab.
///
/// Returns the extracted value, the index of the next component and the index
/// of the next u32 in the slab.
pub fn extract_i8(
// component index, eg 0 for the first 8 bits, 1 for the second 8 bits, etc
n: u32,
// index of the u32 in the slab
u32_index: usize,
// eg 0 for the first 8 bits, 1 for the second 8 bits, etc
byte_offset: usize,
// slab of u32s
slab: &[u32],
) -> (i32, u32, usize) {
let (value, n, u32_index) = extract_u8(n, u32_index, slab);
) -> (i32, usize, usize) {
let (value, u32_index, n) = extract_u8(u32_index, byte_offset, slab);
let value: i32 = (value as i32 & 0xFF) - ((value as i32 & 0x80) << 1);
(value, n, u32_index)
(value, u32_index, n)
}

/// Extract the "nth" 16 bits of the u32 at the given index in the slab.
/// Extract 16 bits of the u32 at the given index in the slab.
pub fn extract_u16(
// component index, eg 0 for the first 16 bits, 1 for the second 16 bits, etc
n: u32,
// index of the u32 in the slab
u32_index: usize,
// eg 0 for the first 16 bits, 2 for the second 16 bits, etc
byte_offset: usize,
// slab of u32s
slab: &[u32],
) -> (u32, u32, usize) {
match n {
0 => (extract(slab[u32_index], U16_0_BITS), 1, u32_index),
_ => (extract(slab[u32_index], U16_1_BITS), 0, u32_index + 1),
}
) -> (u32, usize, usize) {
// NOTE: This should only have two entries, but we'll still handle the case where
// the extraction is not aligned to a u32 boundary by reading as if it were, and then
// re-aligning.
const SHIFT_MASKS: [((u32, u32), usize, usize); 4] = [
(U16_0_BITS, 2, 0),
(U16_0_BITS, 2, 0),
(U16_1_BITS, 0, 1),
(U16_1_BITS, 0, 1),
];
let byte_mod = byte_offset % 4;
crate::println!("byte_mod: {byte_mod}");
let (shift_mask, next_byte_offset, index_inc) = SHIFT_MASKS[byte_mod as usize];
let u32_value = slab.read(Id::from(u32_index));
crate::println!("u32: {:032b}", u32_value);
let value = extract(u32_value, shift_mask);
crate::println!("u16: {:016b}", value);
crate::println!("u32: {:?}", u32_value);
(value, u32_index + index_inc, next_byte_offset)
}

/// Extract the "nth" 16 bits of the u32 at the given index in the slab.
/// Extract 16 bits of the u32 at the given index in the slab.
pub fn extract_i16(
// component index, eg 0 for the first 16 bits, 1 for the second 16 bits, etc
n: u32,
// index of the u32 in the slab
u32_index: usize,
// eg 0 for the first 16 bits, 1 for the second 16 bits, etc
byte_offset: usize,
// slab of u32s
slab: &[u32],
) -> (i32, u32, usize) {
let (value, n, u32_index) = extract_u16(n, u32_index, slab);
) -> (i32, usize, usize) {
let (value, u32_index, n) = extract_u16(u32_index, byte_offset, slab);
let value: i32 = (value as i32 & 0xFFFF) - ((value as i32 & 0x8000) << 1);
(value, n, u32_index)
(value, u32_index, n)
}

/// Extract 32 bits of the u32 at the given index in the slab.
pub fn extract_u32(
// index of the u32 in the slab
u32_index: usize,
// ignored and always passed back as `0`
_byte_offset: usize,
// slab of u32s
slab: &[u32],
) -> (u32, usize, usize) {
(slab.read(Id::from(u32_index)), u32_index + 1, 0)
}

/// Extract 32 bits of the u32 at the given index in the slab.
pub fn extract_i32(
// index of the u32 in the slab
u32_index: usize,
// ignored and always passed back as `0`
_byte_offset: usize,
// slab of u32s
slab: &[u32],
) -> (i32, usize, usize) {
let (value, _, _) = extract_u32(u32_index, 0, slab);
(value as i32, u32_index + 1, 0)
}

/// Extract 32 bits of the u32 at the given index in the slab.
pub fn extract_f32(
// index of the u32 in the slab
u32_index: usize,
// ignored and always passed back as `0`
_byte_offset: usize,
// slab of u32s
slab: &[u32],
) -> (f32, usize, usize) {
let (value, _, _) = extract_u32(u32_index, 0, slab);
(f32::from_bits(value), u32_index + 1, 0)
}

#[cfg(test)]
Expand Down Expand Up @@ -169,12 +228,12 @@ mod test {
let u32_slab: &[u32] = bytemuck::cast_slice(&u8_slab);
let index = 0;
let n = 0;
let (a, n, index) = extract_u8(n, index, u32_slab);
let (b, n, index) = extract_u8(n, index, u32_slab);
let (c, n, index) = extract_u8(n, index, u32_slab);
let (d, n, index) = extract_u8(n, index, u32_slab);
let (e, n, index) = extract_u8(n, index, u32_slab);
let (f, _, _) = extract_u8(n, index, u32_slab);
let (a, index, n) = extract_u8(index, n, u32_slab);
let (b, index, n) = extract_u8(index, n, u32_slab);
let (c, index, n) = extract_u8(index, n, u32_slab);
let (d, index, n) = extract_u8(index, n, u32_slab);
let (e, index, n) = extract_u8(index, n, u32_slab);
let (f, _, _) = extract_u8(index, n, u32_slab);
assert_eq!([0, 1, 2, 3, 4, 5], [a, b, c, d, e, f]);
}

Expand All @@ -184,12 +243,12 @@ mod test {
let u32_slab: &[u32] = bytemuck::cast_slice(&i8_slab);
let index = 0;
let n = 0;
let (a, n, index) = extract_i8(n, index, u32_slab);
let (b, n, index) = extract_i8(n, index, u32_slab);
let (c, n, index) = extract_i8(n, index, u32_slab);
let (d, n, index) = extract_i8(n, index, u32_slab);
let (e, n, index) = extract_i8(n, index, u32_slab);
let (f, _, _) = extract_i8(n, index, u32_slab);
let (a, index, n) = extract_i8(index, n, u32_slab);
let (b, index, n) = extract_i8(index, n, u32_slab);
let (c, index, n) = extract_i8(index, n, u32_slab);
let (d, index, n) = extract_i8(index, n, u32_slab);
let (e, index, n) = extract_i8(index, n, u32_slab);
let (f, _, _) = extract_i8(index, n, u32_slab);
assert_eq!([0, -1, -2, -3, 4, 5], [a, b, c, d, e, f]);
}

Expand All @@ -199,12 +258,12 @@ mod test {
let u32_slab: &[u32] = bytemuck::cast_slice(&u16_slab);
let index = 0;
let n = 0;
let (a, n, index) = extract_u16(n, index, u32_slab);
let (b, n, index) = extract_u16(n, index, u32_slab);
let (c, n, index) = extract_u16(n, index, u32_slab);
let (d, n, index) = extract_u16(n, index, u32_slab);
let (e, n, index) = extract_u16(n, index, u32_slab);
let (f, _, _) = extract_u16(n, index, u32_slab);
let (a, index, n) = extract_u16(index, n, u32_slab);
let (b, index, n) = extract_u16(index, n, u32_slab);
let (c, index, n) = extract_u16(index, n, u32_slab);
let (d, index, n) = extract_u16(index, n, u32_slab);
let (e, index, n) = extract_u16(index, n, u32_slab);
let (f, _, _) = extract_u16(index, n, u32_slab);
assert_eq!([0, 1, 2, 3, 4, 5], [a, b, c, d, e, f]);
}

Expand All @@ -214,13 +273,84 @@ mod test {
let u32_slab: &[u32] = bytemuck::cast_slice(&i16_slab);
let index = 0;
let n = 0;
let (a, n, index) = extract_i16(n, index, u32_slab);
let (b, n, index) = extract_i16(n, index, u32_slab);
let (c, n, index) = extract_i16(n, index, u32_slab);
let (d, n, index) = extract_i16(n, index, u32_slab);
let (e, n, index) = extract_i16(n, index, u32_slab);
let (f, n, index) = extract_i16(n, index, u32_slab);
let (g, _, _) = extract_i16(n, index, u32_slab);
let (a, index, n) = extract_i16(index, n, u32_slab);
let (b, index, n) = extract_i16(index, n, u32_slab);
let (c, index, n) = extract_i16(index, n, u32_slab);
let (d, index, n) = extract_i16(index, n, u32_slab);
let (e, index, n) = extract_i16(index, n, u32_slab);
let (f, index, n) = extract_i16(index, n, u32_slab);
let (g, _, _) = extract_i16(index, n, u32_slab);
assert_eq!([0, -1, -2, -3, 4, 5, -12345], [a, b, c, d, e, f, g]);
}

#[test]
fn extract_u32_sanity() {
let u32_slab = [0u32, 1u32, 2u32, 3u32, 4u32, 5u32];
let u32_slab: &[u32] = bytemuck::cast_slice(&u32_slab);
let index = 0;
let n = 0;
let (a, index, n) = extract_u32(index, n, u32_slab);
let (b, index, n) = extract_u32(index, n, u32_slab);
let (c, index, n) = extract_u32(index, n, u32_slab);
let (d, index, n) = extract_u32(index, n, u32_slab);
let (e, index, n) = extract_u32(index, n, u32_slab);
let (f, _, _) = extract_u32(index, n, u32_slab);
assert_eq!([0, 1, 2, 3, 4, 5], [a, b, c, d, e, f]);
}

#[test]
fn extract_i32_sanity() {
let i32_slab = [0i32, -1i32, -2i32, -3i32, 4i32, 5i32, -12345i32];
let u32_slab: &[u32] = bytemuck::cast_slice(&i32_slab);
let index = 0;
let n = 0;
let (a, index, n) = extract_i32(index, n, u32_slab);
let (b, index, n) = extract_i32(index, n, u32_slab);
let (c, index, n) = extract_i32(index, n, u32_slab);
let (d, index, n) = extract_i32(index, n, u32_slab);
let (e, index, n) = extract_i32(index, n, u32_slab);
let (f, index, n) = extract_i32(index, n, u32_slab);
let (g, _, _) = extract_i32(index, n, u32_slab);
assert_eq!([0, -1, -2, -3, 4, 5, -12345], [a, b, c, d, e, f, g]);
}

#[test]
fn extract_f32_sanity() {
let f32_slab = [
0.0f32,
-1.0f32,
-2.0f32,
-3.0f32,
4.0f32,
5.0f32,
-12345.0f32,
];
let u32_slab: &[u32] = bytemuck::cast_slice(&f32_slab);
let index = 0;
let n = 0;
let (a, index, n) = extract_f32(index, n, u32_slab);
let (b, index, n) = extract_f32(index, n, u32_slab);
let (c, index, n) = extract_f32(index, n, u32_slab);
let (d, index, n) = extract_f32(index, n, u32_slab);
let (e, index, n) = extract_f32(index, n, u32_slab);
let (f, index, n) = extract_f32(index, n, u32_slab);
let (g, _, _) = extract_f32(index, n, u32_slab);
assert_eq!(
[0f32, -1f32, -2f32, -3f32, 4f32, 5f32, -12345f32],
[a, b, c, d, e, f, g]
);
}

#[test]
fn indices_sanity() {
let slab: [u32; 20] = [
65536, 2, 0, 0, 0, 1065353216, 0, 0, 0, 1065353216, 0, 0, 0, 1065353216, 0, 0,
1065353216, 0, 0, 1065353216,
];
let u32_index = 9usize;
let byte_offset = 0usize;
let (a, u32_index, byte_offset) = extract_u32(u32_index, byte_offset, &slab);
let (b, u32_index, byte_offset) = extract_u32(u32_index, byte_offset, &slab);
let (c, u32_index, byte_offset) = extract_u32(u32_index, byte_offset, &slab);
}
}
Loading

0 comments on commit 1d7d349

Please sign in to comment.