ranim_render/graph/
view.rs

1pub mod vitem_compute;
2pub use vitem_compute::*;
3
4pub mod vitem_depth;
5pub use vitem_depth::*;
6
7pub mod vitem_color;
8pub use vitem_color::*;
9
10pub mod mesh_item_depth;
11pub use mesh_item_depth::*;
12
13pub mod mesh_item_color;
14pub use mesh_item_color::*;
15
16use std::ops::{Deref, DerefMut};
17
18use crate::{
19    RenderContext,
20    graph::{GlobalRenderNodeTrait, RenderPacketsQuery},
21    primitives::viewport::ViewportGpuPacket,
22    utils::collections::Graph,
23};
24
25slotmap::new_key_type! { pub struct ViewRenderNodeKey; }
26/// Render graph per-view.
27#[derive(Default)]
28pub struct ViewRenderGraph {
29    inner: Graph<ViewRenderNodeKey, Box<dyn AnyViewRenderNodeTrait + Send + Sync>>,
30}
31
32impl Deref for ViewRenderGraph {
33    type Target = Graph<ViewRenderNodeKey, Box<dyn AnyViewRenderNodeTrait + Send + Sync>>;
34    fn deref(&self) -> &Self::Target {
35        &self.inner
36    }
37}
38
39impl DerefMut for ViewRenderGraph {
40    fn deref_mut(&mut self) -> &mut Self::Target {
41        &mut self.inner
42    }
43}
44
45impl ViewRenderGraph {
46    pub fn new() -> Self {
47        Self::default()
48    }
49    pub fn insert_node(
50        &mut self,
51        node: impl AnyViewRenderNodeTrait + Send + Sync + 'static,
52    ) -> ViewRenderNodeKey {
53        self.inner.insert_node(Box::new(node))
54    }
55}
56
57impl AnyViewRenderNodeTrait for ViewRenderGraph {
58    fn exec(
59        &self,
60        #[cfg(not(feature = "profiling"))] encoder: &mut wgpu::CommandEncoder,
61        #[cfg(feature = "profiling")] scope: &mut wgpu_profiler::Scope<'_, wgpu::CommandEncoder>,
62        render_ctx: RenderContext,
63        viewport: &ViewportGpuPacket,
64    ) {
65        self.iter().for_each(|n| {
66            n.exec(
67                #[cfg(not(feature = "profiling"))]
68                encoder,
69                #[cfg(feature = "profiling")]
70                scope,
71                render_ctx,
72                viewport,
73            );
74        });
75    }
76}
77
78/// A Render Node that is executed per view.
79///
80/// The main difference between this and [`super::AnyGlobalRenderNodeTrait`] is that
81/// is accepts an extra referenced [`ViewportGpuPacket`].
82pub trait ViewRenderNodeTrait {
83    type Query: RenderPacketsQuery;
84    fn run(
85        &self,
86        #[cfg(not(feature = "profiling"))] encoder: &mut wgpu::CommandEncoder,
87        #[cfg(feature = "profiling")] scope: &mut wgpu_profiler::Scope<'_, wgpu::CommandEncoder>,
88        render_packets: <Self::Query as RenderPacketsQuery>::Output<'_>,
89        render_ctx: RenderContext,
90        viewport: &ViewportGpuPacket,
91    );
92}
93
94pub trait AnyViewRenderNodeTrait {
95    fn exec(
96        &self,
97        #[cfg(not(feature = "profiling"))] encoder: &mut wgpu::CommandEncoder,
98        #[cfg(feature = "profiling")] scope: &mut wgpu_profiler::Scope<'_, wgpu::CommandEncoder>,
99        render_ctx: RenderContext,
100        viewport: &ViewportGpuPacket,
101    );
102}
103
104impl<T: ViewRenderNodeTrait> AnyViewRenderNodeTrait for T {
105    fn exec(
106        &self,
107        #[cfg(not(feature = "profiling"))] encoder: &mut wgpu::CommandEncoder,
108        #[cfg(feature = "profiling")] scope: &mut wgpu_profiler::Scope<'_, wgpu::CommandEncoder>,
109        render_ctx: RenderContext,
110        viewport: &ViewportGpuPacket,
111    ) {
112        self.run(
113            #[cfg(not(feature = "profiling"))]
114            encoder,
115            #[cfg(feature = "profiling")]
116            scope,
117            <Self as ViewRenderNodeTrait>::Query::query(render_ctx.render_packets),
118            render_ctx,
119            viewport,
120        );
121    }
122}
123
124impl GlobalRenderNodeTrait for ViewRenderGraph {
125    type Query = ViewportGpuPacket;
126    fn run(
127        &self,
128        #[cfg(not(feature = "profiling"))] encoder: &mut wgpu::CommandEncoder,
129        #[cfg(feature = "profiling")] encoder: &mut wgpu_profiler::Scope<'_, wgpu::CommandEncoder>,
130        viewports: <Self::Query as super::RenderPacketsQuery>::Output<'_>,
131        render_ctx: RenderContext,
132    ) {
133        #[cfg(feature = "profiling")]
134        profiling::scope!("render_view");
135        for viewport in viewports
136            .iter()
137            .map(|v| render_ctx.render_pool.get_packet(v))
138        {
139            self.exec(encoder, render_ctx, viewport);
140        }
141    }
142}