molgfx_render/engine/
settings.rs1use super::{Engine, QualityTier, RenderMode, RenderProfile, ResolvedRenderPlan};
4use crate::engine::graph_setup::realtime_nodes;
5use crate::error::RenderError;
6use crate::graph;
7use molgfx_gpu::{Device, Surface as _, SurfaceConfig};
8
9impl<D: Device> Engine<D> {
10 pub fn resize(&mut self, width: u32, height: u32) {
13 self.width = width.max(1);
14 self.height = height.max(1);
15 self.temporal.reset();
16 if let Some(surface) = &mut self.surface {
17 surface.configure(
18 &self.device,
19 &SurfaceConfig {
20 width: self.width,
21 height: self.height,
22 format: self.target_format,
23 },
24 );
25 }
26 }
27
28 #[must_use]
30 pub fn capabilities(&self) -> &molgfx_gpu::Capabilities {
31 self.device.capabilities()
32 }
33
34 pub fn set_render_mode(&mut self, mode: RenderMode) {
36 if self.mode != mode {
37 self.mode = mode;
38 self.adaptive.set_publication(mode == RenderMode::Cinematic);
41 self.temporal.reset();
42 }
43 }
44
45 #[must_use]
47 pub const fn quality_tier(&self) -> QualityTier {
48 self.adaptive.tier()
49 }
50
51 pub(crate) const fn tier(&self) -> QualityTier {
53 self.adaptive.tier()
54 }
55
56 pub(crate) fn sync_quality_tier(&mut self) {
63 if self.temporal.tier() != self.adaptive.tier() {
64 self.temporal.set_tier(self.adaptive.tier());
65 self.temporal.reset();
66 }
67 }
68
69 #[must_use]
73 pub fn explain(&self) -> String {
74 format!(
75 "quality tier: {:?}\nsmoothed frame time ns: {}\ntarget fps: {}\n{}",
76 self.adaptive.tier(),
77 self.adaptive.smoothed_ns(),
78 self.adaptive.target_fps(),
79 self.scene_gpu.specialization_report()
80 )
81 }
82
83 #[must_use]
85 pub const fn render_mode(&self) -> RenderMode {
86 self.mode
87 }
88
89 pub fn set_render_profile(&mut self, profile: RenderProfile) -> Result<(), RenderError> {
98 if self.profile == profile {
99 return Ok(());
100 }
101 let resolved_plan = profile.resolve();
102 let old_topology = (
103 self.resolved_plan.depth_of_field().is_some(),
104 self.resolved_plan.bloom().is_some(),
105 self.resolved_plan.motion_blur().is_some(),
106 );
107 let new_topology = (
108 resolved_plan.depth_of_field().is_some(),
109 resolved_plan.bloom().is_some(),
110 resolved_plan.motion_blur().is_some(),
111 );
112 if old_topology != new_topology {
113 let pass_nodes = realtime_nodes(new_topology.0, new_topology.1, new_topology.2);
114 let order = graph::schedule(&pass_nodes)?;
115 let depth_of_field = if new_topology.0 && self.passes.depth_of_field.is_none() {
118 Some(crate::passes::DepthOfFieldPass::new(
119 &self.device,
120 &self.scene_gpu.group0_layout,
121 )?)
122 } else {
123 None
124 };
125 let bloom = if new_topology.1 && self.passes.bloom.is_none() {
126 Some(crate::passes::BloomPass::new(
127 &self.device,
128 &self.scene_gpu.group0_layout,
129 )?)
130 } else {
131 None
132 };
133 let motion_blur = if new_topology.2 && self.passes.motion_blur.is_none() {
134 Some(crate::passes::MotionBlurPass::new(
135 &self.device,
136 &self.scene_gpu.group0_layout,
137 )?)
138 } else {
139 None
140 };
141 self.passes.depth_of_field = if new_topology.0 {
142 self.passes.depth_of_field.take().or(depth_of_field)
143 } else {
144 None
145 };
146 self.passes.bloom = if new_topology.1 {
147 self.passes.bloom.take().or(bloom)
148 } else {
149 None
150 };
151 self.passes.motion_blur = if new_topology.2 {
152 self.passes.motion_blur.take().or(motion_blur)
153 } else {
154 None
155 };
156 self.pass_nodes = pass_nodes;
157 self.order = order;
158 self.bindings = None;
159 self.pool = None;
160 }
161 self.resolved_plan = resolved_plan;
162 self.profile = profile;
163 self.temporal.reset();
164 Ok(())
165 }
166
167 pub fn set_derived_cache_budget(&mut self, budget: crate::DerivedCacheBudget) {
172 self.derived_cache.set_budget(budget);
173 }
174
175 #[must_use]
177 pub const fn render_profile(&self) -> &RenderProfile {
178 &self.profile
179 }
180
181 #[must_use]
183 pub const fn resolved_render_plan(&self) -> &ResolvedRenderPlan {
184 &self.resolved_plan
185 }
186}
187
188#[cfg(all(test, not(target_arch = "wasm32")))]
189#[path = "settings_tests.rs"]
190mod tests;