Skip to main content

dsfb_computer_graphics/
cost.rs

1use serde::Serialize;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
4pub enum CostMode {
5    Minimal,
6    HostRealistic,
7    FullResearchDebug,
8}
9
10impl CostMode {
11    pub fn as_str(self) -> &'static str {
12        match self {
13            Self::Minimal => "minimal",
14            Self::HostRealistic => "host_realistic",
15            Self::FullResearchDebug => "full_research_debug",
16        }
17    }
18
19    pub fn label(self) -> &'static str {
20        match self {
21            Self::Minimal => "Minimal mode",
22            Self::HostRealistic => "Host-realistic mode",
23            Self::FullResearchDebug => "Full research/debug mode",
24        }
25    }
26}
27
28#[derive(Clone, Debug, Serialize)]
29pub struct BufferCost {
30    pub name: String,
31    pub bytes_per_pixel: usize,
32    pub notes: String,
33}
34
35#[derive(Clone, Debug, Serialize)]
36pub struct StageCost {
37    pub stage: String,
38    pub approximate_ops_per_pixel: usize,
39    pub approximate_reads_per_pixel: usize,
40    pub approximate_writes_per_pixel: usize,
41    pub reduction_note: String,
42}
43
44#[derive(Clone, Debug, Serialize)]
45pub struct ResolutionFootprint {
46    pub width: usize,
47    pub height: usize,
48    pub total_pixels: usize,
49    pub memory_megabytes: f32,
50}
51
52#[derive(Clone, Debug, Serialize)]
53pub struct CostReport {
54    pub mode: CostMode,
55    pub buffers: Vec<BufferCost>,
56    pub stages: Vec<StageCost>,
57    pub footprints: Vec<ResolutionFootprint>,
58    pub estimated_total_ops_per_pixel: usize,
59    pub estimated_total_reads_per_pixel: usize,
60    pub estimated_total_writes_per_pixel: usize,
61    pub notes: Vec<String>,
62}
63
64pub fn build_cost_report(mode: CostMode) -> CostReport {
65    let (buffers, stages, notes) = match mode {
66        CostMode::Minimal => (
67            vec![
68                buffer("residual", 4, "single-channel scalar residual"),
69                buffer("response", 4, "single-channel hazard / trigger"),
70                buffer("alpha", 4, "single-channel alpha modulation"),
71            ],
72            vec![
73                stage("Residual evaluation", 8, 2, 1, "Fuse with resolve when possible"),
74                stage("Response update", 6, 2, 1, "May be reduced-resolution"),
75                stage("Blend modulation", 6, 2, 1, "Can be fused into TAA resolve"),
76            ],
77            vec![
78                "Minimal mode corresponds to fixed heuristic gating without full trust diagnostics."
79                    .to_string(),
80            ],
81        ),
82        CostMode::HostRealistic => (
83            vec![
84                buffer("residual", 4, "single-channel scalar residual"),
85                buffer("depth disagreement", 4, "single-channel depth cue"),
86                buffer("normal disagreement", 4, "single-channel normal cue"),
87                buffer("motion disagreement", 4, "single-channel motion cue"),
88                buffer("neighborhood inconsistency", 4, "single-channel neighborhood cue"),
89                buffer("trust", 4, "single-channel supervisory trust"),
90                buffer("alpha", 4, "single-channel alpha modulation"),
91                buffer("intervention", 4, "single-channel hazard / response strength"),
92            ],
93            vec![
94                stage("Residual evaluation", 10, 2, 1, "Local arithmetic only"),
95                stage("Depth/normal disagreement", 12, 4, 2, "Can share reprojection fetches"),
96                stage("Motion / neighborhood proxies", 18, 8, 2, "Tile aggregation is viable"),
97                stage("Trust and alpha update", 14, 6, 3, "Trust may run at half resolution"),
98                stage("Blend modulation", 6, 2, 1, "Fuse with temporal resolve"),
99            ],
100            vec![
101                "Host-realistic mode excludes synthetic visibility hints and uses only signals plausible in an engine temporal pipeline."
102                    .to_string(),
103                "The DSFB supervisory layer can be implemented with local operations and limited temporal memory, with expected cost scaling linearly with pixel count and amenable to reduced-resolution evaluation."
104                    .to_string(),
105                "The framework is compatible with tiled and asynchronous GPU execution."
106                    .to_string(),
107            ],
108        ),
109        CostMode::FullResearchDebug => (
110            vec![
111                buffer("residual", 4, "single-channel scalar residual"),
112                buffer("visibility hint", 4, "synthetic comparison/debug-only visibility cue"),
113                buffer("depth disagreement", 4, "single-channel depth cue"),
114                buffer("normal disagreement", 4, "single-channel normal cue"),
115                buffer("motion disagreement", 4, "single-channel motion cue"),
116                buffer("neighborhood inconsistency", 4, "single-channel neighborhood cue"),
117                buffer("thin proxy", 4, "single-channel thin/local-contrast cue"),
118                buffer("history instability", 4, "single-channel history instability cue"),
119                buffer("trust", 4, "single-channel supervisory trust"),
120                buffer("alpha", 4, "single-channel alpha modulation"),
121                buffer("intervention", 4, "single-channel hazard / response strength"),
122                buffer("state labels", 1, "debug structural-state labels"),
123            ],
124            vec![
125                stage("Residual evaluation", 10, 2, 1, "Local arithmetic only"),
126                stage("All proxy synthesis", 26, 12, 5, "Debug mode keeps all intermediate fields"),
127                stage("Grammar / trust update", 18, 8, 3, "Tile aggregation remains possible"),
128                stage("Alpha / intervention update", 8, 2, 2, "May be fused downstream"),
129                stage("Debug output writes", 4, 0, 5, "Debug-only cost, not required in deployment"),
130            ],
131            vec![
132                "Full research/debug mode keeps all intermediate cues and state exports for ablation and report generation."
133                    .to_string(),
134                "Synthetic visibility hints in this mode are intended only for comparison, not as a deployment claim."
135                    .to_string(),
136            ],
137        ),
138    };
139
140    let estimated_total_ops_per_pixel = stages
141        .iter()
142        .map(|stage| stage.approximate_ops_per_pixel)
143        .sum();
144    let estimated_total_reads_per_pixel = stages
145        .iter()
146        .map(|stage| stage.approximate_reads_per_pixel)
147        .sum();
148    let estimated_total_writes_per_pixel = stages
149        .iter()
150        .map(|stage| stage.approximate_writes_per_pixel)
151        .sum();
152    let bytes_per_pixel = buffers
153        .iter()
154        .map(|buffer| buffer.bytes_per_pixel)
155        .sum::<usize>();
156    let footprints = [(1280usize, 720usize), (1920, 1080), (3840, 2160)]
157        .into_iter()
158        .map(|(width, height)| ResolutionFootprint {
159            width,
160            height,
161            total_pixels: width * height,
162            memory_megabytes: bytes_per_pixel as f32 * (width * height) as f32 / (1024.0 * 1024.0),
163        })
164        .collect();
165
166    CostReport {
167        mode,
168        buffers,
169        stages,
170        footprints,
171        estimated_total_ops_per_pixel,
172        estimated_total_reads_per_pixel,
173        estimated_total_writes_per_pixel,
174        notes,
175    }
176}
177
178fn buffer(name: &str, bytes_per_pixel: usize, notes: &str) -> BufferCost {
179    BufferCost {
180        name: name.to_string(),
181        bytes_per_pixel,
182        notes: notes.to_string(),
183    }
184}
185
186fn stage(
187    stage: &str,
188    approximate_ops_per_pixel: usize,
189    approximate_reads_per_pixel: usize,
190    approximate_writes_per_pixel: usize,
191    reduction_note: &str,
192) -> StageCost {
193    StageCost {
194        stage: stage.to_string(),
195        approximate_ops_per_pixel,
196        approximate_reads_per_pixel,
197        approximate_writes_per_pixel,
198        reduction_note: reduction_note.to_string(),
199    }
200}