Skip to main content

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    /// Presentation submissions not yet reported complete by the GPU.
61    pub pending_frame_submissions: u32,
62    /// Monotonic identifier for the most recently submitted frame.
63    pub last_submission_id: u64,
64    /// Submission timestamp in the engine monotonic clock, in nanoseconds:
65    /// host time when the frame's encoder reached the queue. CPU cost of the
66    /// frame is separately observable as the duration of the native `render`
67    /// call; this is not device execution time.
68    pub submission_timestamp_ns: u64,
69    /// Host timestamp when the last submission's fence was observed complete,
70    /// in the same monotonic clock. `None` while the frame is pending, and
71    /// `None` on native backends because the engine only observes the fence on
72    /// the browser path; even when set, this is host-observation latency, not
73    /// exact device completion or GPU execution time. GPU execution time
74    /// requires timestamp queries via the profiling path.
75    pub completion_timestamp_ns: Option<u64>,
76    /// Retained recomputable device bytes.
77    pub derived_cache_gpu_bytes: u64,
78    /// Peak recomputable device bytes since engine construction.
79    pub derived_cache_peak_gpu_bytes: u64,
80    /// Live physical GPU buffer bytes owned through the device boundary.
81    pub physical_buffer_bytes: u64,
82    /// Live physical GPU texture bytes owned through the device boundary.
83    pub physical_texture_bytes: u64,
84    /// Total live physical GPU bytes owned through the device boundary.
85    pub physical_total_bytes: u64,
86    /// Peak live physical GPU bytes since device construction.
87    pub physical_peak_bytes: u64,
88}
89
90/// Explicit frame status, completeness and degradation report.
91#[derive(Clone, Copy, PartialEq, Eq, Debug)]
92pub struct FrameReport {
93    /// Presentation result.
94    pub status: FrameStatus,
95    /// Whether full requested detail was available.
96    pub completeness: FrameCompleteness,
97    /// Explicit approximations used by the selected mode.
98    pub degradation: FrameDegradation,
99    /// Residency counters captured after submission.
100    pub metrics: FrameMetrics,
101    /// True while temporal convergence, streaming, or surface recovery needs
102    /// another caller-scheduled frame.
103    pub needs_another_frame: bool,
104    /// The adaptive quality tier this frame rendered at.
105    pub quality_tier: QualityTier,
106}
107
108/// Which rendering mode the engine runs.
109#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
110pub enum RenderMode {
111    /// The interactive raster path.
112    #[default]
113    Realtime,
114    /// Progressive, deterministic high-fidelity rendering. Camera motion
115    /// resets temporal history but never changes the selected render path.
116    Cinematic,
117}
118
119/// Engine construction options.
120#[derive(Clone, Debug)]
121pub struct EngineConfig {
122    /// Adapter preference.
123    pub power: PowerPreference,
124    /// Initial frame width, pixels.
125    pub width: u32,
126    /// Initial frame height, pixels.
127    pub height: u32,
128    /// Rendering strategy. Backend selection remains capability-driven.
129    pub mode: RenderMode,
130    /// Adaptive quality policy. A configuration that disables adaptation
131    /// holds one tier, so converged output stays reproducible.
132    pub adaptive: AdaptiveQualityConfig,
133    /// Reusable presentation recipe resolved once during engine construction.
134    pub profile: RenderProfile,
135    /// Fixed page, staging, command and lifecycle capacities.
136    pub residency: ResidencyConfig,
137    /// One coordinated limit set for caller/provider-owned source data.
138    pub source_budget: ResidencyBudget,
139    /// Hard limits for recomputable data, separate from source residency.
140    pub derived_cache: DerivedCacheBudget,
141    /// Hard ceiling for live physical GPU buffers and textures.
142    pub resource_memory_limit_bytes: Option<u64>,
143    /// Maximum number of simultaneously resident dataset/namespace pick pages.
144    pub picking_page_capacity: u32,
145}
146
147impl Default for EngineConfig {
148    fn default() -> Self {
149        Self {
150            power: PowerPreference::HighPerformance,
151            width: 1280,
152            height: 800,
153            mode: RenderMode::Realtime,
154            adaptive: AdaptiveQualityConfig::default(),
155            profile: RenderProfile::inspection(),
156            residency: ResidencyConfig::default(),
157            source_budget: ResidencyBudget::default(),
158            derived_cache: DerivedCacheBudget::default(),
159            resource_memory_limit_bytes: None,
160            picking_page_capacity: 1_024,
161        }
162    }
163}
164
165#[cfg(test)]
166#[path = "config_tests.rs"]
167mod tests;