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    /// 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;