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