ranim_render/graph/
mod.rs1use std::ops::{Deref, DerefMut};
2
3pub mod view;
4
5pub mod clear;
6pub use clear::*;
7
8pub mod oit_resolve;
9pub use oit_resolve::*;
10
11use variadics_please::all_tuples;
12
13use crate::{
14 RenderContext,
15 primitives::viewport::ViewportGpuPacket,
16 resource::Handle,
17 utils::collections::{Graph, TypeBinnedVec},
18};
19
20slotmap::new_key_type! { pub struct GlobalRenderNodeKey; }
21#[derive(Default)]
25pub struct GlobalRenderGraph {
26 inner: Graph<GlobalRenderNodeKey, Box<dyn AnyGlobalRenderNodeTrait + Send + Sync>>,
27}
28
29impl Deref for GlobalRenderGraph {
30 type Target = Graph<GlobalRenderNodeKey, Box<dyn AnyGlobalRenderNodeTrait + Send + Sync>>;
31 fn deref(&self) -> &Self::Target {
32 &self.inner
33 }
34}
35
36impl DerefMut for GlobalRenderGraph {
37 fn deref_mut(&mut self) -> &mut Self::Target {
38 &mut self.inner
39 }
40}
41
42impl GlobalRenderGraph {
43 pub fn new() -> Self {
44 Self::default()
45 }
46 pub fn insert_node(
47 &mut self,
48 node: impl AnyGlobalRenderNodeTrait + Send + Sync + 'static,
49 ) -> GlobalRenderNodeKey {
50 self.inner.insert_node(Box::new(node))
51 }
52}
53
54impl AnyGlobalRenderNodeTrait for GlobalRenderGraph {
55 fn exec(
56 &self,
57 #[cfg(not(feature = "profiling"))] encoder: &mut wgpu::CommandEncoder,
58 #[cfg(feature = "profiling")] encoder: &mut wgpu_profiler::Scope<'_, wgpu::CommandEncoder>,
59 render_ctx: RenderContext,
60 ) {
61 self.iter().for_each(|n| {
62 n.exec(encoder, render_ctx);
63 });
64 }
65}
66
67pub trait AnyGlobalRenderNodeTrait {
68 fn exec(
69 &self,
70 #[cfg(not(feature = "profiling"))] encoder: &mut wgpu::CommandEncoder,
71 #[cfg(feature = "profiling")] scope: &mut wgpu_profiler::Scope<'_, wgpu::CommandEncoder>,
72 render_ctx: RenderContext,
73 );
74}
75impl<T: GlobalRenderNodeTrait> AnyGlobalRenderNodeTrait for T {
76 fn exec(
77 &self,
78 #[cfg(not(feature = "profiling"))] encoder: &mut wgpu::CommandEncoder,
79 #[cfg(feature = "profiling")] encoder: &mut wgpu_profiler::Scope<'_, wgpu::CommandEncoder>,
80 render_ctx: RenderContext,
81 ) {
82 self.run(
83 encoder,
84 <Self as GlobalRenderNodeTrait>::Query::query(render_ctx.render_packets),
85 render_ctx,
86 );
87 }
88}
89
90pub trait GlobalRenderNodeTrait {
91 type Query: RenderPacketsQuery;
92 fn run(
93 &self,
94 #[cfg(not(feature = "profiling"))] encoder: &mut wgpu::CommandEncoder,
95 #[cfg(feature = "profiling")] encoder: &mut wgpu_profiler::Scope<'_, wgpu::CommandEncoder>,
96 render_packets: <Self::Query as RenderPacketsQuery>::Output<'_>,
97 render_ctx: RenderContext,
98 );
99}
100
101pub trait RenderPacketsQuery {
102 type Output<'s>;
103 fn query(store: &RenderPackets) -> Self::Output<'_>;
104}
105
106pub trait RenderPacketMark {}
108impl RenderPacketMark for ViewportGpuPacket {}
109
110impl<T: RenderPacketMark + Send + Sync + 'static> RenderPacketsQuery for T {
111 type Output<'s> = &'s [Handle<T>];
112 fn query(store: &RenderPackets) -> Self::Output<'_> {
113 store.get()
114 }
115}
116
117impl RenderPacketsQuery for () {
118 type Output<'s> = ();
119 fn query(_store: &RenderPackets) -> Self::Output<'_> {}
120}
121
122macro_rules! impl_tuple_render_packet_query {
123 ($($T:ident),*) => {
124 impl<$($T: RenderPacketMark + Send + Sync + 'static,)*> RenderPacketsQuery for ($($T,)*) {
125 type Output<'s> = ($(&'s [Handle<$T>],)*);
126 fn query(store: &RenderPackets) -> Self::Output<'_> {
127 ($(store.get::<$T>(),)*)
128 }
129 }
130 };
131}
132
133all_tuples!(impl_tuple_render_packet_query, 1, 16, T);
134
135#[derive(Default)]
139pub struct RenderPackets {
140 inner: TypeBinnedVec,
141}
142
143impl RenderPackets {
144 #[inline]
145 pub fn get<T: RenderPacketMark + Send + Sync + 'static>(&self) -> &[Handle<T>] {
146 self.inner.get_row::<Handle<T>>()
147 }
148 #[inline]
149 pub fn extend<T: RenderPacketMark + Send + Sync + 'static>(
150 &mut self,
151 packets: impl IntoIterator<Item = Handle<T>>,
152 ) {
153 self.inner.extend(packets);
154 }
155 #[inline]
156 pub fn push<T: RenderPacketMark + Send + Sync + 'static>(&mut self, packet: Handle<T>) {
157 self.inner.push(packet);
158 }
159 #[inline]
160 pub fn clear(&mut self) {
161 self.inner.clear();
162 }
163}