use anyhow::anyhow; const DEPTH_INFINITY: u32 = 0x7c00; const DEPTH_SIZE: usize = DEPTH_INFINITY as usize + 1; #[derive(Default)] pub struct SortBuffers { pub readback: Vec, pub ordering: Vec, pub buckets: Vec, } impl SortBuffers { pub fn ensure_size(&mut self, max_splats: usize) { if self.readback.len() < max_splats { self.readback.resize(max_splats, 0); } if self.ordering.len() < max_splats { self.ordering.resize(max_splats, 0); } if self.buckets.len() < DEPTH_SIZE { self.buckets.resize(DEPTH_SIZE, 0); } } } pub fn sort_internal(buffers: &mut SortBuffers, num_splats: usize) -> anyhow::Result { let SortBuffers { readback, ordering, buckets } = buffers; let readback = &readback[..num_splats]; // Set the bucket counts to zero buckets.clear(); buckets.resize(DEPTH_SIZE, 0); // Count the number of splats in each bucket for &metric in readback.iter() { if (metric as u32) < DEPTH_INFINITY { buckets[metric as usize] += 1; } } // Compute bucket starting offset let mut active_splats = 0; for count in buckets.iter_mut().rev().skip(1) { let new_total = active_splats + *count; *count = active_splats; active_splats = new_total; } // Write out splat indices at the right location using bucket offsets for (index, &metric) in readback.iter().enumerate() { if (metric as u32) < DEPTH_INFINITY { ordering[buckets[metric as usize] as usize] = index as u32; buckets[metric as usize] += 1; } } // Sanity check if buckets[0] != active_splats { return Err(anyhow!( "Expected {} active splats but got {}", active_splats, buckets[0] )); } Ok(active_splats) }