molgfx_render/engine/config.rs
1//! Engine configuration and frame outcomes.
2
3use super::{AdaptiveQualityConfig, DerivedCacheBudget, QualityTier, RenderProfile};
4use crate::ResidencyConfig;
5use molgfx_core::ResidencyBudget;
6use molgfx_gpu::PowerPreference;
7
8/// Presentation result independent of streaming completeness.
9#[derive(Clone, Copy, PartialEq, Eq, Debug)]
10pub enum FrameStatus {
11 /// The frame reached the presentation surface.
12 Presented,
13 /// The frame was skipped (surface lost or outdated); the surface was
14 /// reconfigured and the next call recovers.
15 Skipped,
16}
17
18/// Whether every requested resource contributed at full fidelity.
19#[derive(Clone, Copy, PartialEq, Eq, Debug)]
20pub enum FrameCompleteness {
21 /// No provider or upload work remains pending.
22 Complete,
23 /// The frame is valid but more resident detail is still arriving.
24 Progressive {
25 /// Bounded uploads awaiting fence completion.
26 pending_chunks: u64,
27 },
28}
29
30/// Allocation-free bitset describing explicit realtime degradation.
31#[derive(Clone, Copy, Default, PartialEq, Eq, Debug)]
32pub struct FrameDegradation(u8);
33
34impl FrameDegradation {
35 /// Non-resident detail is represented by the paged/proxy path.
36 pub const STREAMING_PROXY: Self = Self(1);
37
38 /// True when every bit in `feature` is active.
39 #[must_use]
40 pub const fn contains(self, feature: Self) -> bool {
41 self.0 & feature.0 == feature.0
42 }
43
44 pub(super) const fn streaming_proxy(enabled: bool) -> Self {
45 if enabled {
46 Self::STREAMING_PROXY
47 } else {
48 Self(0)
49 }
50 }
51}
52
53/// Stable, allocation-free counters captured with a frame report.
54#[derive(Clone, Copy, Default, PartialEq, Eq, Debug)]
55pub struct FrameMetrics {
56 /// Provider chunks tracked by the GPU residency layer.
57 pub tracked_chunks: usize,
58 /// Upload bytes still protected by GPU fences.
59 pub upload_in_flight_bytes: u64,
60 /// Retained recomputable device bytes.
61 pub derived_cache_gpu_bytes: u64,
62 /// Peak recomputable device bytes since engine construction.
63 pub derived_cache_peak_gpu_bytes: u64,
64 /// Live physical GPU buffer bytes owned through the device boundary.
65 pub physical_buffer_bytes: u64,
66 /// Live physical GPU texture bytes owned through the device boundary.
67 pub physical_texture_bytes: u64,
68 /// Total live physical GPU bytes owned through the device boundary.
69 pub physical_total_bytes: u64,
70 /// Peak live physical GPU bytes since device construction.
71 pub physical_peak_bytes: u64,
72}
73
74/// Explicit frame status, completeness and degradation report.
75#[derive(Clone, Copy, PartialEq, Eq, Debug)]
76pub struct FrameReport {
77 /// Presentation result.
78 pub status: FrameStatus,
79 /// Whether full requested detail was available.
80 pub completeness: FrameCompleteness,
81 /// Explicit approximations used by the selected mode.
82 pub degradation: FrameDegradation,
83 /// Residency counters captured after submission.
84 pub metrics: FrameMetrics,
85 /// True while temporal convergence, streaming, or surface recovery needs
86 /// another caller-scheduled frame.
87 pub needs_another_frame: bool,
88 /// The adaptive quality tier this frame rendered at.
89 pub quality_tier: QualityTier,
90}
91
92/// Which rendering mode the engine runs.
93#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
94pub enum RenderMode {
95 /// The interactive raster path.
96 #[default]
97 Realtime,
98 /// Progressive, deterministic high-fidelity rendering. Camera motion
99 /// resets temporal history but never changes the selected render path.
100 Cinematic,
101}
102
103/// Engine construction options.
104#[derive(Clone, Debug)]
105pub struct EngineConfig {
106 /// Adapter preference.
107 pub power: PowerPreference,
108 /// Initial frame width, pixels.
109 pub width: u32,
110 /// Initial frame height, pixels.
111 pub height: u32,
112 /// Rendering strategy. Backend selection remains capability-driven.
113 pub mode: RenderMode,
114 /// Adaptive quality policy. A configuration that disables adaptation
115 /// holds one tier, so converged output stays reproducible.
116 pub adaptive: AdaptiveQualityConfig,
117 /// Reusable presentation recipe resolved once during engine construction.
118 pub profile: RenderProfile,
119 /// Fixed page, staging, command and lifecycle capacities.
120 pub residency: ResidencyConfig,
121 /// One coordinated limit set for caller/provider-owned source data.
122 pub source_budget: ResidencyBudget,
123 /// Hard limits for recomputable data, separate from source residency.
124 pub derived_cache: DerivedCacheBudget,
125 /// Hard ceiling for live physical GPU buffers and textures.
126 pub resource_memory_limit_bytes: Option<u64>,
127 /// Maximum number of simultaneously resident dataset/namespace pick pages.
128 pub picking_page_capacity: u32,
129}
130
131impl Default for EngineConfig {
132 fn default() -> Self {
133 Self {
134 power: PowerPreference::HighPerformance,
135 width: 1280,
136 height: 800,
137 mode: RenderMode::Realtime,
138 adaptive: AdaptiveQualityConfig::default(),
139 profile: RenderProfile::inspection(),
140 residency: ResidencyConfig::default(),
141 source_budget: ResidencyBudget::default(),
142 derived_cache: DerivedCacheBudget::default(),
143 resource_memory_limit_bytes: None,
144 picking_page_capacity: 1_024,
145 }
146 }
147}
148
149#[cfg(test)]
150#[path = "config_tests.rs"]
151mod tests;