diff --git a/crates/renderer/src/render_graph.rs b/crates/renderer/src/render_graph.rs index 8c078bd..6a09145 100644 --- a/crates/renderer/src/render_graph.rs +++ b/crates/renderer/src/render_graph.rs @@ -493,6 +493,7 @@ impl RenderGraph { let mut topological_map = Vec::new(); let mut top_dag = dag.clone(); + let mut root_barriers = BTreeMap::new(); // create topological map of DAG from sink to source loop { @@ -514,20 +515,40 @@ impl RenderGraph { .for_each(|edge| { let (rid, (before, after)) = edge.weight(); - barriers - .entry(*rid) - .and_modify(|(from, to)| { - *from = *from | *before; - *to = *to | *after; - }) - .or_insert((*before, *after)); + // initial access is transitioned at the beginning + // this affects imported resources only. + if edge.source() == root { + &mut root_barriers + } else { + &mut barriers + } + .entry(*rid) + .and_modify(|(from, to)| { + *from = *from | *before; + *to = *to | *after; + }) + .or_insert((*before, *after)); }); top_dag.remove_node(sink); } + let passes = passes + .into_iter() + .filter_map(|pass| { + if let PassNode::Pass(i) = pass { + Some(i) + } else { + None + } + }) + .map(|i| core::mem::take(&mut self.pass_descs[i])) + .collect::>(); + topological_map.push((passes, barriers)); } + topological_map.push((vec![], root_barriers)); + //tracing::debug!("mapping: {topological_map:#?}"); // I don't think this can currently happen with the way passes are added. top_dag.remove_node(root); if top_dag.node_count() > 0 { @@ -546,48 +567,35 @@ impl RenderGraph { let resources = &self.resources; let cmds = topological_map - .iter() + .into_iter() .rev() - .map(|(set, accesses)| { - let pool = pool.clone(); - let device = device.clone(); - let passes = set - .into_iter() - .filter_map(|pass| { - if let &PassNode::Pass(i) = pass { - Some(i) - } else { - None - } - }) - .map(|i| core::mem::take(&mut self.pass_descs[i])) - .collect::>(); + .map({ + |(passes, accesses)| { + let cmd = pool.alloc()?; + // transitions + for (&id, &(from, to)) in accesses.iter() { + Self::transition_resource( + resources.get(&id).unwrap(), + device.dev(), + unsafe { &cmd.buffer() }, + from, + to, + ); + } - let cmd = pool.alloc()?; + let ctx = RenderContext { + device: device.clone(), + cmd, + resources, + }; - // transitions - for (&id, &(from, to)) in accesses.iter() { - Self::transition_resource( - resources.get(&id).unwrap(), - device.dev(), - unsafe { &cmd.buffer() }, - from, - to, - ); + for pass in passes { + (pass.record)(&ctx)?; + } + + ctx.cmd.end()?; + crate::Result::Ok(ctx.cmd) } - - let ctx = RenderContext { - device, - cmd, - resources, - }; - - for pass in passes { - (pass.record)(&ctx)?; - } - - ctx.cmd.end()?; - crate::Result::Ok(ctx.cmd) }) .collect::>>()?;