From 5ff58348f273c9d099f67f9a86739e1ce426e24d Mon Sep 17 00:00:00 2001 From: Matt Keeter Date: Wed, 21 Feb 2024 17:34:36 -0500 Subject: [PATCH 1/2] Get wasm build working --- .github/workflows/wasm.yml | 20 ++++++++++++++++++++ Cargo.lock | 3 +++ fidget/Cargo.toml | 3 +++ fidget/src/mesh/builder.rs | 2 ++ fidget/src/mesh/cell.rs | 32 +++++++++++++++----------------- fidget/src/mesh/dc.rs | 15 +++++++++++++-- fidget/src/mesh/fixup.rs | 2 ++ fidget/src/mesh/mt/dc.rs | 27 ++++++++++++++++----------- 8 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/wasm.yml diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml new file mode 100644 index 00000000..bef6515c --- /dev/null +++ b/.github/workflows/wasm.yml @@ -0,0 +1,20 @@ +name: Check wasm build + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Build + run: cargo check --target=wasm32-unknown-unknown --release -pfidget --no-default-features --features="rhai,render,mesh" diff --git a/Cargo.lock b/Cargo.lock index 4d7cddd9..46bb97d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -816,6 +816,7 @@ dependencies = [ "crossbeam-deque", "document-features", "dynasmrt", + "getrandom", "ieee754", "libc", "nalgebra", @@ -906,8 +907,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] diff --git a/fidget/Cargo.toml b/fidget/Cargo.toml index ff927aaf..b5713b72 100644 --- a/fidget/Cargo.toml +++ b/fidget/Cargo.toml @@ -33,6 +33,9 @@ nalgebra = { version = "0.31" } crossbeam-deque = { version = "0.8", optional = true } workspace-hack = { version = "0.1", path = "../workspace-hack" } +[target.'cfg(target_arch = "wasm32")'.dependencies] +getrandom = { version = "0.2", features = ["js"] } + [features] default = ["jit", "rhai", "render", "mesh"] diff --git a/fidget/src/mesh/builder.rs b/fidget/src/mesh/builder.rs index 69ec4087..181a8a31 100644 --- a/fidget/src/mesh/builder.rs +++ b/fidget/src/mesh/builder.rs @@ -24,6 +24,8 @@ impl MeshBuilder { } impl DcBuilder for MeshBuilder { + type VertexIndex = usize; + fn cell(&mut self, octree: &Octree, cell: CellIndex) { dc::dc_cell(octree, cell, self); } diff --git a/fidget/src/mesh/cell.rs b/fidget/src/mesh/cell.rs index 1458b813..a5a80df7 100644 --- a/fidget/src/mesh/cell.rs +++ b/fidget/src/mesh/cell.rs @@ -41,11 +41,6 @@ impl std::fmt::Debug for CellData { } } -static_assertions::const_assert_eq!( - std::mem::size_of::(), - std::mem::size_of::() -); - /// Unpacked form of [`CellData`] #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Cell { @@ -74,22 +69,25 @@ impl Cell { impl From for Cell { fn from(c: CellData) -> Self { - let i = c.0 as usize; + let i = c.0; match i { 0 => Cell::Invalid, 1 => Cell::Empty, 2 => Cell::Full, - _ => match (i >> 62) & 0b11 { - 0b10 => Cell::Branch { - index: i & ((1 << 54) - 1), - thread: (i >> 54) as u8, - }, - 0b11 => Cell::Leaf(Leaf { - mask: (i >> 54) as u8, - index: i & ((1 << 54) - 1), - }), - _ => panic!("invalid cell encoding"), - }, + _ => { + let index = (i & ((1 << 54) - 1)).try_into().unwrap(); + match (i >> 62) & 0b11 { + 0b10 => Cell::Branch { + thread: (i >> 54) as u8, + index, + }, + 0b11 => Cell::Leaf(Leaf { + mask: (i >> 54) as u8, + index, + }), + _ => panic!("invalid cell encoding"), + } + } } } } diff --git a/fidget/src/mesh/dc.rs b/fidget/src/mesh/dc.rs index e95169d7..7f7a2119 100644 --- a/fidget/src/mesh/dc.rs +++ b/fidget/src/mesh/dc.rs @@ -8,6 +8,12 @@ use crate::mesh::{ }; pub trait DcBuilder { + /// Type for vertex indexes + /// + /// This is typically a `usize`, but we'll sometimes explicitly force it to + /// be a `u64` if we're planning to use upper bits for flags. + type VertexIndex: Copy + Clone; + fn cell(&mut self, octree: &Octree, cell: CellIndex); fn face(&mut self, octree: &Octree, a: CellIndex, b: CellIndex); @@ -49,7 +55,12 @@ pub trait DcBuilder { /// /// The vertices are given in a clockwise winding with the intersection /// vertex (i.e. the one on the edge) always last. - fn triangle(&mut self, a: usize, b: usize, c: usize); + fn triangle( + &mut self, + a: Self::VertexIndex, + b: Self::VertexIndex, + c: Self::VertexIndex, + ); /// Looks up the given vertex, localizing it within a cell /// @@ -60,7 +71,7 @@ pub trait DcBuilder { v: usize, cell: CellIndex, verts: &[CellVertex], - ) -> usize; + ) -> Self::VertexIndex; } pub fn dc_cell(octree: &Octree, cell: CellIndex, out: &mut B) { diff --git a/fidget/src/mesh/fixup.rs b/fidget/src/mesh/fixup.rs index 9ed4e105..da129e1b 100644 --- a/fidget/src/mesh/fixup.rs +++ b/fidget/src/mesh/fixup.rs @@ -33,6 +33,8 @@ impl DcFixup { } impl DcBuilder for DcFixup { + type VertexIndex = usize; + fn cell(&mut self, octree: &Octree, cell: CellIndex) { if let Cell::Leaf(Leaf { index, mask }) = octree.cells[cell.index].into() diff --git a/fidget/src/mesh/mt/dc.rs b/fidget/src/mesh/mt/dc.rs index 524b6b0c..f8a433d7 100644 --- a/fidget/src/mesh/mt/dc.rs +++ b/fidget/src/mesh/mt/dc.rs @@ -7,7 +7,7 @@ use crate::mesh::{ types::{X, Y, Z}, Mesh, Octree, }; -use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::atomic::{AtomicU64, Ordering}; #[derive(Debug)] enum Task { @@ -42,8 +42,8 @@ pub struct DcWorker<'a> { /// - The top bit is always 1 (so 0 is not a valid claimed index) /// - The next 8 bits indicate which thread has claimed the vertex /// - The remaining bits are an index into that thread's [`DcWorker::verts`] - map: &'a [AtomicUsize], - tris: Vec>, + map: &'a [AtomicU64], + tris: Vec>, verts: Vec>, /// Our personal queue of tasks to complete, along with references to other @@ -58,7 +58,7 @@ impl<'a> DcWorker<'a> { let map = octree .verts .iter() - .map(|_| AtomicUsize::new(0)) + .map(|_| AtomicU64::new(0)) .collect::>(); let mut workers = queues @@ -132,8 +132,9 @@ impl<'a> DcWorker<'a> { .iter_mut() .zip(tris.iter().map(|t| { t.map(|v| { - let thread = (v >> 55) & 0xFF; - let i = v & ((1 << 55) - 1); + let thread = ((v >> 55) & 0xFF) as usize; + let i: usize = + (v & ((1 << 55) - 1)).try_into().unwrap(); vert_offsets_ref[thread] + i }) })) @@ -152,7 +153,7 @@ impl<'a> DcWorker<'a> { pub fn run( mut self, pool: &ThreadPool, - ) -> (Vec>, Vec>) { + ) -> (Vec>, Vec>) { let mut ctx = pool.start(self.thread_index); loop { @@ -202,6 +203,10 @@ impl<'a> DcWorker<'a> { #[allow(clippy::modulo_one, clippy::identity_op, unused_parens)] impl DcBuilder for DcWorker<'_> { + // We need to reserve 1 byte for multithreading info, so we'll force the use + // of a u64 here (rather than a usize, which is 32-bit on some platforms) + type VertexIndex = u64; + fn cell(&mut self, _octree: &Octree, cell: CellIndex) { self.queue.push(Task::Cell(cell)); } @@ -231,7 +236,7 @@ impl DcBuilder for DcWorker<'_> { } } - fn triangle(&mut self, a: usize, b: usize, c: usize) { + fn triangle(&mut self, a: u64, b: u64, c: u64) { self.tris.push(nalgebra::Vector3::new(a, b, c)) } @@ -245,12 +250,12 @@ impl DcBuilder for DcWorker<'_> { i: usize, _cell: CellIndex, verts: &[CellVertex], - ) -> usize { + ) -> u64 { // Build our thread + vertex index - let mut next = self.verts.len(); + let mut next = self.verts.len() as u64; assert!(next < (1 << 55)); next |= 1 << 63; - next |= self.thread_index << 55; + next |= (self.thread_index as u64) << 55; match self.map[i].compare_exchange( 0, From 23214f582838454208702a0dc5e8d56026a4f23d Mon Sep 17 00:00:00 2001 From: Matt Keeter Date: Wed, 21 Feb 2024 17:44:49 -0500 Subject: [PATCH 2/2] Poking at CI --- .github/workflows/wasm.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index bef6515c..0d65f312 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -16,5 +16,7 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Build + - name: Install wasm target + run: rustup target add wasm32-unknown-unknown + - name: Check run: cargo check --target=wasm32-unknown-unknown --release -pfidget --no-default-features --features="rhai,render,mesh"