fn visit_node(
    graph: &RenderGraphBuilder,
    node_id: RenderGraphNodeId,
    visited: &mut Vec<bool>,
    visiting: &mut Vec<bool>,
    visiting_stack: &mut Vec<RenderGraphNodeId>,
    ordered_list: &mut Vec<RenderGraphNodeId>,
) {
    // This node is already visited and inserted into ordered_list
    if visited[node_id.0] {
        return;
    }

    // This node is already being visited higher up in the stack. This indicates a cycle in the
    // graph
    if visiting[node_id.0] {
        log::warn!("Found cycle in graph");
        log::warn!("{:?}", graph.node(node_id));
        for v in visiting_stack.iter().rev() {
            log::warn!("{:?}", graph.node(*v));
        }
        panic!("Graph has a cycle");
    }

    // When we enter the node, mark the node as being in-progress of being visited to help
    // detect cycles in the graph
    visiting[node_id.0] = true;
    visiting_stack.push(node_id);

    //
    // Visit children
    //
    //log::trace!("  Begin visit {:?}", node_id);
    let node = graph.node(node_id);

    //
    // Visit all the nodes we aren't delaying
    //
    for read in &node.image_reads {
        let upstream_node = graph.image_version_info(read.image).creator_node;
        visit_node(
            graph,
            upstream_node,
            visited,
            visiting,
            visiting_stack,
            ordered_list,
        );
    }

    for modify in &node.image_modifies {
        let upstream_node = graph.image_version_info(modify.input).creator_node;
        visit_node(
            graph,
            upstream_node,
            visited,
            visiting,
            visiting_stack,
            ordered_list,
        );
    }

    for read in &node.buffer_reads {
        let upstream_node = graph.buffer_version_info(read.buffer).creator_node;
        visit_node(
            graph,
            upstream_node,
            visited,
            visiting,
            visiting_stack,
            ordered_list,
        );
    }

    for modify in &node.buffer_modifies {
        let upstream_node = graph.buffer_version_info(modify.input).creator_node;
        visit_node(
            graph,
            upstream_node,
            visited,
            visiting,
            visiting_stack,
            ordered_list,
        );
    }

    for &explicit_dependency in &node.explicit_dependencies {
        visit_node(
            graph,
            explicit_dependency,
            visited,
            visiting,
            visiting_stack,
            ordered_list,
        );
    }

    // All our pre-requisites were visited, so it's now safe to push this node onto the
    // orderered list
    ordered_list.push(node_id);
    visited[node_id.0] = true;

    // We are no longer visiting this node
    //log::trace!("  End visit {:?}", node_id);
    visiting_stack.pop();
    visiting[node_id.0] = false;
}
// Recursively called to topologically sort the nodes to determine execution order. See
// determine_node_order which kicks this off.
// https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search
Recursively called to topologically sort the nodes to determine execution order. See
determine_node_order which kicks this off.
Recursively called to topologically sort the nodes to determine execution order . See determine_node_order which kicks this off .
fn visit_node(
    graph: &RenderGraphBuilder,
    node_id: RenderGraphNodeId,
    visited: &mut Vec<bool>,
    visiting: &mut Vec<bool>,
    visiting_stack: &mut Vec<RenderGraphNodeId>,
    ordered_list: &mut Vec<RenderGraphNodeId>,
) {
    // This node is already visited and inserted into ordered_list
    if visited[node_id.0] {
        return;
    }
    // This node is already being visited higher up in the stack. This indicates a cycle in the
    // graph
    if visiting[node_id.0] {
        log::warn!("Found cycle in graph");
        log::warn!("{:?}", graph.node(node_id));
        for v in visiting_stack.iter().rev() {
            log::warn!("{:?}", graph.node(*v));
        }
        panic!("Graph has a cycle");
    }
    // When we enter the node, mark the node as being in-progress of being visited to help
    // detect cycles in the graph
    visiting[node_id.0] = true;
    visiting_stack.push(node_id);
    //
    // Visit children
    //
    //log::trace!("  Begin visit {:?}", node_id);
    let node = graph.node(node_id);
    //
    // Visit all the nodes we aren't delaying
    //
    for read in &node.image_reads {
        let upstream_node = graph.image_version_info(read.image).creator_node;
        visit_node(
            graph,
            upstream_node,
            visited,
            visiting,
            visiting_stack,
            ordered_list,
        );
    }
    for modify in &node.image_modifies {
        let upstream_node = graph.image_version_info(modify.input).creator_node;
        visit_node(
            graph,
            upstream_node,
            visited,
            visiting,
            visiting_stack,
            ordered_list,
        );
    }
    for read in &node.buffer_reads {
        let upstream_node = graph.buffer_version_info(read.buffer).creator_node;
        visit_node(
            graph,
            upstream_node,
            visited,
            visiting,
            visiting_stack,
            ordered_list,
        );
    }
    for modify in &node.buffer_modifies {
        let upstream_node = graph.buffer_version_info(modify.input).creator_node;
        visit_node(
            graph,
            upstream_node,
            visited,
            visiting,
            visiting_stack,
            ordered_list,
        );
    }
    for &explicit_dependency in &node.explicit_dependencies {
        visit_node(
            graph,
            explicit_dependency,
            visited,
            visiting,
            visiting_stack,
            ordered_list,
        );
    }
    // All our pre-requisites were visited, so it's now safe to push this node onto the
    // orderered list
    ordered_list.push(node_id);
    visited[node_id.0] = true;
    // We are no longer visiting this node
    //log::trace!("  End visit {:?}", node_id);
    visiting_stack.pop();
    visiting[node_id.0] = false;
}
fn visit_node ( graph : & RenderGraphBuilder , node_id : RenderGraphNodeId , visited : & mut Vec < bool > , visiting : & mut Vec < bool > , visiting_stack : & mut Vec < RenderGraphNodeId > , ordered_list : & mut Vec < RenderGraphNodeId > , ) { // This node is already visited and inserted into ordered_list if visited [ node_id . 0 ] { return ; } // This node is already being visited higher up in the stack. This indicates a cycle in the // graph if visiting [ node_id . 0 ] { log :: warn ! ( " " ) ; log :: warn ! ( " " graph node ( node_id ) ) ; for v in visiting_stack . iter ( ) . rev ( ) { log :: warn ! ( " " graph node ( v ) ) ; } panic ! ( " " ) ; } // When we enter the node, mark the node as being in-progress of being visited to help // detect cycles in the graph visiting [ node_id . 0 ] = true ; visiting_stack . push ( node_id ) ; // // Visit children // //log::trace!("  Begin visit {:?}", node_id); let node = graph . node ( node_id ) ; // // Visit all the nodes we aren't delaying // for read in & node . image_reads { let upstream_node = graph . image_version_info ( read . image ) . creator_node ; visit_node ( graph , upstream_node , visited , visiting , visiting_stack , ordered_list , ) ; } for modify in & node . image_modifies { let upstream_node = graph . image_version_info ( modify . input ) . creator_node ; visit_node ( graph , upstream_node , visited , visiting , visiting_stack , ordered_list , ) ; } for read in & node . buffer_reads { let upstream_node = graph . buffer_version_info ( read . buffer ) . creator_node ; visit_node ( graph , upstream_node , visited , visiting , visiting_stack , ordered_list , ) ; } for modify in & node . buffer_modifies { let upstream_node = graph . buffer_version_info ( modify . input ) . creator_node ; visit_node ( graph , upstream_node , visited , visiting , visiting_stack , ordered_list , ) ; } for & explicit_dependency in & node . explicit_dependencies { visit_node ( graph , explicit_dependency , visited , visiting , visiting_stack , ordered_list , ) ; } // All our pre-requisites were visited, so it's now safe to push this node onto the // orderered list ordered_list . push ( node_id ) ; visited [ node_id . 0 ] = true ; // We are no longer visiting this node //log::trace!("  End visit {:?}", node_id); visiting_stack . pop ( ) ; visiting [ node_id . 0 ] = false ; }
Recursively called to topologically sort the nodes to determine execution order.
Recursively called to topologically sort the nodes to determine execution order .
graph
&RenderGraphBuilder
node_id
RenderGraphNodeId
visited
&mut Vec<bool>
visiting
&mut Vec<bool>
visiting_stack
&mut Vec<RenderGraphNodeId>
ordered_list
&mut Vec<RenderGraphNodeId>
graph
&RenderGraphBuilder
node_id
RenderGraphNodeId
visited
&mut Vec<bool>
visiting
&mut Vec<bool>
visiting_stack
&mut Vec<RenderGraphNodeId>
ordered_list
&mut Vec<RenderGraphNodeId>