1use crate::{
2 BufferDesc, BufferId, BufferResource, ComputePassDesc, NodeKey, ParamKey, ParamSlot,
3 ParamTarget, Pass, PassDesc, PassId, Program, ProgramDesc, ProgramId, RenderPassDesc,
4 SamplerId, SamplerResource, TextureDesc, TextureId, TextureResource,
5};
6
7#[derive(Debug, Clone)]
8pub struct RenderPlan {
9 pub(crate) textures: Vec<TextureResource>,
10 pub(crate) buffers: Vec<BufferResource>,
11 pub(crate) samplers: Vec<SamplerResource>,
12 pub(crate) programs: Vec<Program>,
13 pub(crate) passes: Vec<Pass>,
14 params: Vec<ParamSlot>,
15}
16
17impl RenderPlan {
18 pub fn builder() -> RenderPlanBuilder {
19 RenderPlanBuilder::default()
20 }
21
22 pub fn textures(&self) -> &[TextureResource] {
23 &self.textures
24 }
25
26 pub fn buffers(&self) -> &[BufferResource] {
27 &self.buffers
28 }
29
30 pub fn samplers(&self) -> &[SamplerResource] {
31 &self.samplers
32 }
33
34 pub fn programs(&self) -> &[Program] {
35 &self.programs
36 }
37
38 pub fn passes(&self) -> &[Pass] {
39 &self.passes
40 }
41
42 pub fn params(&self) -> &[ParamSlot] {
43 &self.params
44 }
45}
46
47#[derive(Debug, Default)]
48pub struct RenderPlanBuilder {
49 textures: Vec<TextureResource>,
50 buffers: Vec<BufferResource>,
51 samplers: Vec<SamplerResource>,
52 programs: Vec<Program>,
53 passes: Vec<Pass>,
54 params: Vec<ParamSlot>,
55}
56
57impl RenderPlanBuilder {
58 pub fn texture(&mut self, label: impl Into<Option<String>>, desc: TextureDesc) -> TextureId {
59 let id = TextureId(self.textures.len() as u32);
60 self.textures.push(TextureResource {
61 id,
62 label: label.into(),
63 desc,
64 owner: None,
65 });
66 id
67 }
68
69 pub fn texture_for(
70 &mut self,
71 owner: NodeKey,
72 label: impl Into<Option<String>>,
73 desc: TextureDesc,
74 ) -> TextureId {
75 let id = self.texture(label, desc);
76 self.textures[id.0 as usize].owner = Some(owner);
77 id
78 }
79
80 pub fn buffer(&mut self, label: impl Into<Option<String>>, desc: BufferDesc) -> BufferId {
81 let id = BufferId(self.buffers.len() as u32);
82 self.buffers.push(BufferResource {
83 id,
84 label: label.into(),
85 desc,
86 owner: None,
87 });
88 id
89 }
90
91 pub fn buffer_for(
92 &mut self,
93 owner: NodeKey,
94 label: impl Into<Option<String>>,
95 desc: BufferDesc,
96 ) -> BufferId {
97 let id = self.buffer(label, desc);
98 self.buffers[id.0 as usize].owner = Some(owner);
99 id
100 }
101
102 pub fn sampler(
103 &mut self,
104 label: impl Into<Option<String>>,
105 desc: wgpu::SamplerDescriptor<'static>,
106 ) -> SamplerId {
107 let id = SamplerId(self.samplers.len() as u32);
108 self.samplers.push(SamplerResource {
109 id,
110 label: label.into(),
111 desc,
112 });
113 id
114 }
115
116 pub fn program(&mut self, desc: ProgramDesc) -> ProgramId {
117 let id = ProgramId(self.programs.len() as u32);
118 self.programs.push(Program {
119 id,
120 owner: None,
121 desc,
122 });
123 id
124 }
125
126 pub fn program_for(&mut self, owner: NodeKey, desc: ProgramDesc) -> ProgramId {
127 let id = self.program(desc);
128 self.programs[id.0 as usize].owner = Some(owner);
129 id
130 }
131
132 pub fn render_pass(&mut self, desc: RenderPassDesc) -> PassId {
133 self.pass(PassDesc::Render(desc))
134 }
135
136 pub fn compute_pass(&mut self, desc: ComputePassDesc) -> PassId {
137 self.pass(PassDesc::Compute(desc))
138 }
139
140 pub fn copy_texture(&mut self, desc: crate::CopyTextureDesc) -> PassId {
141 self.pass(PassDesc::CopyTexture(desc))
142 }
143
144 pub fn param(&mut self, key: ParamKey, target: ParamTarget) -> &mut Self {
145 self.params.push(ParamSlot { key, target });
146 self
147 }
148
149 pub fn build(self) -> RenderPlan {
150 RenderPlan {
151 textures: self.textures,
152 buffers: self.buffers,
153 samplers: self.samplers,
154 programs: self.programs,
155 passes: self.passes,
156 params: self.params,
157 }
158 }
159
160 fn pass(&mut self, desc: PassDesc) -> PassId {
161 let id = PassId(self.passes.len() as u32);
162 self.passes.push(Pass { id, desc });
163 id
164 }
165}