rafx_framework/render_features/jobs/prepare/
prepare_job.rs1use crate::render_features::render_features_prelude::*;
2use std::marker::PhantomData;
3use std::ops::Range;
4
5pub struct PrepareJob<'prepare, PrepareJobEntryPointsT: PrepareJobEntryPoints<'prepare>> {
10 inner: PrepareJobEntryPointsT,
11 prepare_context: RenderJobPrepareContext<'prepare>,
12 frame_packet: Option<Box<FramePacket<PrepareJobEntryPointsT::FramePacketDataT>>>,
13 submit_packet: Option<Box<SubmitPacket<PrepareJobEntryPointsT::SubmitPacketDataT>>>,
14 #[allow(dead_code)]
15 debug_constants: &'static RenderFeatureDebugConstants,
16 _phantom: (PhantomData<&'prepare ()>,),
17}
18
19impl<'prepare, PrepareJobEntryPointsT: 'prepare + PrepareJobEntryPoints<'prepare>>
20 PrepareJob<'prepare, PrepareJobEntryPointsT>
21{
22 pub fn new(
23 inner: PrepareJobEntryPointsT,
24 prepare_context: &RenderJobPrepareContext<'prepare>,
25 frame_packet: Box<FramePacket<PrepareJobEntryPointsT::FramePacketDataT>>,
26 submit_packet: Box<SubmitPacket<PrepareJobEntryPointsT::SubmitPacketDataT>>,
27 ) -> Self {
28 let debug_constants = inner.feature_debug_constants();
29 Self {
30 inner,
31 prepare_context: prepare_context.clone(),
32 frame_packet: Some(frame_packet),
33 submit_packet: Some(submit_packet),
34 debug_constants,
35 _phantom: Default::default(),
36 }
37 }
38
39 fn frame_packet(&self) -> &Option<Box<FramePacket<PrepareJobEntryPointsT::FramePacketDataT>>> {
40 &self.frame_packet
41 }
42
43 fn view_packets(&self) -> &Vec<ViewPacket<PrepareJobEntryPointsT::FramePacketDataT>> {
44 &self.frame_packet.as_ref().unwrap().view_packets()
45 }
46
47 fn render_object_instances(&self) -> &Vec<RenderObjectInstance> {
48 &self.frame_packet.as_ref().unwrap().render_object_instances
49 }
50
51 fn submit_packet(
52 &self
53 ) -> &Option<Box<SubmitPacket<PrepareJobEntryPointsT::SubmitPacketDataT>>> {
54 &self.submit_packet
55 }
56
57 fn force_to_prepare_lifetime(
58 &self,
59 inner: &PrepareJobEntryPointsT,
60 ) -> &'prepare PrepareJobEntryPointsT {
61 unsafe {
62 std::mem::transmute::<_, &'prepare PrepareJobEntryPointsT>(inner)
66 }
67 }
68}
69
70impl<'prepare, PrepareJobEntryPointsT: 'prepare + PrepareJobEntryPoints<'prepare>>
71 RenderFeaturePrepareJob<'prepare> for PrepareJob<'prepare, PrepareJobEntryPointsT>
72{
73 fn begin_per_frame_prepare(&self) {
74 profiling::scope!(self.debug_constants.begin_per_frame_prepare);
75
76 let context = PreparePerFrameContext::new(
77 &self.prepare_context,
78 self.frame_packet.as_ref().unwrap(),
79 self.submit_packet.as_ref().unwrap(),
80 );
81 self.inner.begin_per_frame_prepare(&context);
82 }
83
84 fn prepare_render_object_instance(
85 &self,
86 range: Range<usize>,
87 ) {
88 if range.is_empty() {
89 return;
90 }
91
92 let mut job_context = {
93 let inner = self.force_to_prepare_lifetime(&self.inner);
94 inner.new_render_object_instance_job_context()
95 };
96
97 if job_context.is_none() {
98 return;
99 }
100
101 profiling::scope!(self.debug_constants.prepare_render_object_instance);
102
103 let job_context = job_context.as_mut().unwrap();
104 let frame_packet = self.frame_packet.as_ref().unwrap();
105 let submit_packet = self.submit_packet.as_ref().unwrap();
106 for id in range {
107 let context = PrepareRenderObjectInstanceContext::new(
108 &self.prepare_context,
109 frame_packet,
110 submit_packet,
111 id,
112 );
113 self.inner
114 .prepare_render_object_instance(job_context, &context);
115 }
116 }
117
118 fn view_packet(
119 &self,
120 view_index: ViewFrameIndex,
121 ) -> &dyn RenderFeatureViewPacket {
122 self.frame_packet()
123 .as_ref()
124 .unwrap()
125 .render_feature_view_packet(view_index)
126 }
127
128 fn view_submit_packet(
129 &self,
130 view_index: ViewFrameIndex,
131 ) -> &dyn RenderFeatureViewSubmitPacket {
132 self.submit_packet()
133 .as_ref()
134 .unwrap()
135 .render_feature_view_submit_packet(view_index)
136 }
137
138 fn prepare_render_object_instance_per_view(
139 &self,
140 view_packet: &dyn RenderFeatureViewPacket,
141 view_submit_packet: &dyn RenderFeatureViewSubmitPacket,
142 range: Range<usize>,
143 ) {
144 if range.is_empty() {
145 return;
146 }
147
148 let mut job_context = {
149 let inner = self.force_to_prepare_lifetime(&self.inner);
150 inner.new_render_object_instance_per_view_job_context()
151 };
152
153 if job_context.is_none() {
154 return;
155 }
156
157 profiling::scope!(self.debug_constants.prepare_render_object_instance_per_view);
158
159 let job_context = job_context.as_mut().unwrap();
160 let frame_packet = self.frame_packet.as_ref().unwrap();
161 let submit_packet = self.submit_packet.as_ref().unwrap();
162
163 let view_packet: &ViewPacket<PrepareJobEntryPointsT::FramePacketDataT> =
164 view_packet.as_concrete();
165
166 let view_submit_packet: &ViewSubmitPacket<PrepareJobEntryPointsT::SubmitPacketDataT> =
167 view_submit_packet.as_concrete();
168
169 for id in range {
170 let context = PrepareRenderObjectInstancePerViewContext::new(
171 &self.prepare_context,
172 frame_packet,
173 submit_packet,
174 view_packet,
175 view_submit_packet,
176 id,
177 );
178 self.inner
179 .prepare_render_object_instance_per_view(job_context, &context);
180 }
181 }
182
183 fn end_per_view_prepare(
184 &self,
185 view_packet: &dyn RenderFeatureViewPacket,
186 view_submit_packet: &dyn RenderFeatureViewSubmitPacket,
187 ) {
188 profiling::scope!(self.debug_constants.end_per_view_prepare);
189
190 let view_packet: &ViewPacket<PrepareJobEntryPointsT::FramePacketDataT> =
191 view_packet.as_concrete();
192
193 let view_submit_packet: &ViewSubmitPacket<PrepareJobEntryPointsT::SubmitPacketDataT> =
194 view_submit_packet.as_concrete();
195
196 let context = PreparePerViewContext::new(
197 &self.prepare_context,
198 self.frame_packet.as_ref().unwrap(),
199 self.submit_packet.as_ref().unwrap(),
200 view_packet,
201 view_submit_packet,
202 );
203
204 self.inner.end_per_view_prepare(&context);
205 }
206
207 fn end_per_frame_prepare(&self) {
208 profiling::scope!(self.debug_constants.end_per_frame_prepare);
209
210 let context = PreparePerFrameContext::new(
211 &self.prepare_context,
212 self.frame_packet.as_ref().unwrap(),
213 self.submit_packet.as_ref().unwrap(),
214 );
215 self.inner.end_per_frame_prepare(&context);
216 }
217
218 fn num_views(&self) -> usize {
219 self.view_packets().len()
220 }
221
222 fn num_render_object_instances(&self) -> usize {
223 self.render_object_instances().len()
224 }
225
226 fn take_frame_packet(&mut self) -> Box<dyn RenderFeatureFramePacket> {
227 std::mem::take(&mut self.frame_packet).unwrap()
228 }
229
230 fn take_submit_packet(&mut self) -> Box<dyn RenderFeatureSubmitPacket> {
231 std::mem::take(&mut self.submit_packet).unwrap()
232 }
233
234 fn feature_debug_constants(&self) -> &'static RenderFeatureDebugConstants {
235 self.inner.feature_debug_constants()
236 }
237
238 fn feature_index(&self) -> RenderFeatureIndex {
239 self.inner.feature_index()
240 }
241}