rafx_framework/render_features/
render_views.rs1use crate::render_features::registry::MAX_RENDER_FEATURE_COUNT;
2use crate::render_features::{
3 RenderFeature, RenderFeatureFlag, RenderFeatureFlagMask, RenderFeatureIndex, RenderFeatureMask,
4 RenderPhase, RenderPhaseIndex, RenderPhaseMask, ViewFrameIndex,
5};
6use crate::visibility::ViewFrustumArc;
7use glam::{Mat4, Vec3};
8use rafx_visibility::{DepthRange, Projection};
9use std::mem::MaybeUninit;
10use std::sync::atomic::Ordering;
11use std::sync::atomic::{AtomicI32, AtomicU32};
12use std::sync::Arc;
13
14pub type RenderViewIndex = u32;
15pub type RenderViewCount = u32;
16
17pub struct RenderViewSet {
18 view_count: AtomicU32,
19 frame_index: usize,
20}
21
22impl RenderViewSet {
23 pub fn new(frame_index: usize) -> Self {
24 RenderViewSet {
25 view_count: Default::default(),
26 frame_index,
27 }
28 }
29
30 pub fn create_view(
31 &self,
32 view_frustum: ViewFrustumArc,
33 eye_position: Vec3,
34 view: Mat4,
35 proj: Mat4,
36 extents: (u32, u32),
37 depth_range: RenderViewDepthRange,
38 render_phase_mask: RenderPhaseMask,
39 render_feature_mask: RenderFeatureMask,
40 render_feature_flag_mask: RenderFeatureFlagMask,
41 debug_name: String,
42 ) -> RenderView {
43 let view_index = self.view_count.fetch_add(1, Ordering::Release);
44 RenderView::new(
45 view_frustum,
46 view_index,
47 eye_position,
48 view,
49 proj,
50 extents,
51 depth_range,
52 render_phase_mask,
53 render_feature_mask,
54 render_feature_flag_mask,
55 debug_name,
56 self.frame_index,
57 )
58 }
59
60 pub fn view_count(&self) -> RenderViewCount {
61 self.view_count.load(Ordering::Acquire)
62 }
63}
64
65pub struct RenderViewInner {
67 view_frustum: ViewFrustumArc,
68 eye_position: Vec3,
69 view: Mat4,
70 proj: Mat4,
71 view_proj: Mat4,
72 view_dir: Vec3,
73 view_index: RenderViewIndex,
74 view_frame_indices: [AtomicI32; MAX_RENDER_FEATURE_COUNT as usize],
75 extents: (u32, u32),
77 depth_range: RenderViewDepthRange,
78 render_phase_mask: RenderPhaseMask,
79 render_feature_mask: RenderFeatureMask,
80 render_feature_flag_mask: RenderFeatureFlagMask,
81 debug_name: String,
82 frame_index: usize,
83}
84
85#[derive(Clone)]
86pub struct RenderViewDepthRange {
87 pub near: f32,
88 pub far: Option<f32>, pub reversed: bool,
90}
91
92impl RenderViewDepthRange {
93 pub fn new(
94 near: f32,
95 far: f32,
96 ) -> Self {
97 RenderViewDepthRange {
98 near,
99 far: Some(far),
100 reversed: false,
101 }
102 }
103
104 pub fn from_projection(projection: &Projection) -> Self {
105 let near = projection.near_distance();
106 let far = projection.far_distance();
107 match projection.depth_range() {
108 DepthRange::Normal => RenderViewDepthRange::new(near, far),
109 DepthRange::Infinite => RenderViewDepthRange::new_infinite(near),
110 DepthRange::Reverse => RenderViewDepthRange::new_reverse(near, far),
111 DepthRange::InfiniteReverse => RenderViewDepthRange::new_infinite_reverse(near),
112 }
113 }
114
115 pub fn new_infinite(near: f32) -> Self {
116 RenderViewDepthRange {
117 near,
118 far: None,
119 reversed: false,
120 }
121 }
122
123 pub fn new_reverse(
124 near: f32,
125 far: f32,
126 ) -> Self {
127 RenderViewDepthRange {
128 near,
129 far: Some(far),
130 reversed: true,
131 }
132 }
133
134 pub fn new_infinite_reverse(near: f32) -> Self {
135 RenderViewDepthRange {
136 near,
137 far: None,
138 reversed: true,
139 }
140 }
141
142 pub fn planes_after_reverse(&self) -> (Option<f32>, Option<f32>) {
145 if self.reversed {
146 (self.far, Some(self.near))
147 } else {
148 (Some(self.near), self.far)
149 }
150 }
151
152 pub fn finite_planes_after_reverse(&self) -> Option<(f32, f32)> {
153 if self.reversed {
154 Some((self.far?, self.near))
155 } else {
156 Some((self.near, self.far?))
157 }
158 }
159
160 pub fn planes_before_reverse(&self) -> (f32, Option<f32>) {
161 (self.near, self.far)
162 }
163}
164
165fn init_view_frame_indices() -> [AtomicI32; MAX_RENDER_FEATURE_COUNT as usize] {
167 let mut view_count_by_feature: [MaybeUninit<AtomicI32>; MAX_RENDER_FEATURE_COUNT as usize] =
168 unsafe { MaybeUninit::uninit().assume_init() };
169
170 for data in &mut view_count_by_feature {
171 data.write(AtomicI32::new(-1));
172 }
173
174 unsafe { std::mem::transmute(view_count_by_feature) }
175}
176
177#[derive(Clone)]
183pub struct RenderView {
184 inner: Arc<RenderViewInner>,
185}
186
187impl RenderView {
188 pub fn view_mat4_to_view_dir(view: &glam::Mat4) -> glam::Vec3 {
190 glam::Vec3::new(view.x_axis.z, view.y_axis.z, view.z_axis.z) * -1.0
191 }
192
193 pub fn new(
194 view_frustum: ViewFrustumArc,
195 view_index: RenderViewIndex,
196 eye_position: Vec3,
197 view: Mat4,
198 proj: Mat4,
199 extents: (u32, u32),
200 depth_range: RenderViewDepthRange,
201 render_phase_mask: RenderPhaseMask,
202 render_feature_mask: RenderFeatureMask,
203 render_feature_flag_mask: RenderFeatureFlagMask,
204 debug_name: String,
205 frame_index: usize,
206 ) -> RenderView {
207 let view_dir = Self::view_mat4_to_view_dir(&view);
208
209 let inner = RenderViewInner {
210 view_frustum,
211 eye_position,
212 view,
213 proj,
214 view_proj: proj * view,
215 view_dir,
216 view_index,
217 view_frame_indices: init_view_frame_indices(),
218 extents,
219 depth_range,
220 render_phase_mask,
221 render_feature_mask,
222 render_feature_flag_mask,
223 debug_name,
224 frame_index,
225 };
226
227 RenderView {
228 inner: Arc::new(inner),
229 }
230 }
231
232 pub fn frame_index(&self) -> usize {
233 self.inner.frame_index
234 }
235
236 pub fn view_frustum(&self) -> ViewFrustumArc {
237 self.inner.view_frustum.clone()
238 }
239
240 pub fn eye_position(&self) -> Vec3 {
241 self.inner.eye_position
242 }
243
244 pub fn view_dir(&self) -> Vec3 {
245 self.inner.view_dir
246 }
247
248 pub fn view_matrix(&self) -> Mat4 {
249 self.inner.view
250 }
251
252 pub fn projection_matrix(&self) -> Mat4 {
253 self.inner.proj
254 }
255
256 pub fn view_proj(&self) -> Mat4 {
257 self.inner.view_proj
258 }
259
260 pub fn view_index(&self) -> RenderViewIndex {
261 self.inner.view_index
262 }
263
264 pub fn set_view_frame_index(
265 &self,
266 feature_index: RenderFeatureIndex,
267 view_frame_index: ViewFrameIndex,
268 ) {
269 let old_view_frame_index = self.inner.view_frame_indices[feature_index as usize]
270 .swap(view_frame_index as i32, Ordering::Relaxed);
271 assert!(old_view_frame_index == -1);
272 }
273
274 pub fn view_frame_index(
275 &self,
276 feature_index: RenderFeatureIndex,
277 ) -> Option<ViewFrameIndex> {
278 let view_frame_index =
279 self.inner.view_frame_indices[feature_index as usize].load(Ordering::Relaxed);
280 if view_frame_index != -1 {
281 Some(view_frame_index as ViewFrameIndex)
282 } else {
283 None
284 }
285 }
286
287 pub fn extents(&self) -> (u32, u32) {
288 self.inner.extents
289 }
290
291 pub fn extents_vec2(&self) -> glam::Vec2 {
292 glam::Vec2::new(self.inner.extents.0 as f32, self.inner.extents.1 as f32)
293 }
294
295 pub fn extents_width(&self) -> u32 {
296 self.inner.extents.0
297 }
298
299 pub fn extents_height(&self) -> u32 {
300 self.inner.extents.1
301 }
302
303 pub fn depth_range(&self) -> &RenderViewDepthRange {
304 &self.inner.depth_range
305 }
306
307 pub fn debug_name(&self) -> &str {
308 &self.inner.debug_name
309 }
310
311 pub fn phase_is_relevant<RenderPhaseT: RenderPhase>(&self) -> bool {
312 self.inner.render_phase_mask.is_included::<RenderPhaseT>()
313 }
314
315 pub fn phase_index_is_relevant(
316 &self,
317 phase_index: RenderPhaseIndex,
318 ) -> bool {
319 self.inner.render_phase_mask.is_included_index(phase_index)
320 }
321
322 pub fn render_phase_mask(&self) -> RenderPhaseMask {
323 self.inner.render_phase_mask
324 }
325
326 pub fn feature_is_relevant<RenderFeatureT: RenderFeature>(&self) -> bool {
327 self.inner
328 .render_feature_mask
329 .is_included::<RenderFeatureT>()
330 }
331
332 pub fn feature_index_is_relevant(
333 &self,
334 feature_index: RenderFeatureIndex,
335 ) -> bool {
336 self.inner
337 .render_feature_mask
338 .is_included_index(feature_index)
339 }
340
341 pub fn render_feature_mask(&self) -> RenderFeatureMask {
342 self.inner.render_feature_mask
343 }
344
345 pub fn is_relevant<RenderPhaseT: RenderPhase, RenderFeatureT: RenderFeature>(&self) -> bool {
346 self.phase_is_relevant::<RenderPhaseT>() && self.feature_is_relevant::<RenderFeatureT>()
347 }
348
349 pub fn index_is_relevant(
350 &self,
351 phase_index: RenderPhaseIndex,
352 feature_index: RenderFeatureIndex,
353 ) -> bool {
354 self.phase_index_is_relevant(phase_index) && self.feature_index_is_relevant(feature_index)
355 }
356
357 pub fn feature_flag_is_relevant<RenderFeatureFlagT: RenderFeatureFlag>(&self) -> bool {
358 self.inner
359 .render_feature_flag_mask
360 .is_included::<RenderFeatureFlagT>()
361 }
362
363 pub fn feature_flag_index_is_relevant(
364 &self,
365 feature_flag_index: RenderFeatureIndex,
366 ) -> bool {
367 self.inner
368 .render_feature_flag_mask
369 .is_included_index(feature_flag_index)
370 }
371
372 pub fn render_feature_flag_mask(&self) -> RenderFeatureFlagMask {
373 self.inner.render_feature_flag_mask
374 }
375}