(
&mut self,
scene: &mut crate::scene::SceneGraph,
encoder: &mut wgpu::CommandEncoder,
)
| 7521 | } |
| 7522 | |
| 7523 | fn rebuild_acceleration_structures( |
| 7524 | &mut self, |
| 7525 | scene: &mut crate::scene::SceneGraph, |
| 7526 | encoder: &mut wgpu::CommandEncoder, |
| 7527 | ) { |
| 7528 | // V4 — SW path also needs a populated instance_data buffer |
| 7529 | // for its broad-phase hit lookup. Collect instance handles |
| 7530 | // (nodes with a card slot, stable scene order) first, then |
| 7531 | // branch on `hw_rt_enabled` for TLAS/BLAS-specific work. |
| 7532 | let pending_blas = !scene.pending_blas_builds.is_empty(); |
| 7533 | let version_changed = scene.tlas_version != self.tlas_built_version; |
| 7534 | if !pending_blas && !version_changed { |
| 7535 | return; |
| 7536 | } |
| 7537 | |
| 7538 | let mut instance_handles: Vec<f64> = Vec::new(); |
| 7539 | for (h, n) in scene.nodes.iter() { |
| 7540 | if n.visible && n.card_first_slot.is_some() { |
| 7541 | instance_handles.push(h); |
| 7542 | } |
| 7543 | } |
| 7544 | let (instance_count, _resized) = self.rebuild_instance_data(scene, &instance_handles); |
| 7545 | |
| 7546 | // Everything below this point is HW-ray-tracing-specific |
| 7547 | // (TLAS build + BLAS batch). On SW adapters we're done. |
| 7548 | if !self.hw_rt_enabled { |
| 7549 | self.tlas_built_version = scene.tlas_version; |
| 7550 | return; |
| 7551 | } |
| 7552 | |
| 7553 | let pending = pending_blas; |
| 7554 | if instance_count == 0 && !pending { |
| 7555 | return; |
| 7556 | } |
| 7557 | |
| 7558 | if self.tlas.is_none() || instance_count > self.tlas_max_instances { |
| 7559 | let cap = self.tlas_max_instances.max(64); |
| 7560 | self.tlas = Some(self.device.create_tlas(&wgpu::CreateTlasDescriptor { |
| 7561 | label: Some("bloom_tlas"), |
| 7562 | max_instances: cap, |
| 7563 | flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, |
| 7564 | update_mode: wgpu::AccelerationStructureUpdateMode::Build, |
| 7565 | })); |
| 7566 | self.probe_trace_hw_bg_cache = [None, None]; |
| 7567 | // V14 — same reason as the resize path above. |
| 7568 | self.wsrc_bake_hw_bg_cache = None; |
| 7569 | } |
| 7570 | |
| 7571 | // Populate TLAS instance slots. Clear stale entries from prior |
| 7572 | // rebuilds by writing `None` over every slot up to the current |
| 7573 | // instance count (extras beyond stay None from the initial vec). |
| 7574 | { |
| 7575 | let tlas = self.tlas.as_mut().unwrap(); |
| 7576 | for slot in 0..(instance_count as usize) { |
| 7577 | let n = scene.nodes.get(instance_handles[slot]).unwrap(); |
| 7578 | let blas = n.blas.as_ref().unwrap(); |
| 7579 | let t = &n.transform; |
| 7580 | // TlasInstance expects a row-major 3x4 affine transform |
no test coverage detected