valo_renderer/report.rs
1//! `report` accounts for resources retained between frames.
2//!
3//! Pool byte counts are estimates derived from resource descriptors, not
4//! queried from the driver. wgpu's own counters are included when the
5//! `counters` feature is on.
6
7/// `PoolReport` summarizes one resource pool or cache.
8#[derive(Clone, Copy, Debug, Default)]
9pub struct PoolReport {
10 /// `count` is the number of live entries.
11 pub count: u32,
12 /// `bytes` is their estimated memory usage.
13 pub bytes: u64,
14}
15
16/// `AtlasReport` summarizes one glyph-atlas family.
17#[derive(Clone, Copy, Debug, Default)]
18pub struct AtlasReport {
19 /// `pages` is the number of allocated atlas textures.
20 pub pages: u32,
21 /// `bytes` is their estimated GPU memory usage.
22 pub bytes: u64,
23 /// `entries` is the number of resident rasterized glyphs.
24 ///
25 /// Whitespace placeholders are excluded.
26 pub entries: u32,
27}
28
29/// `WgpuCounters` reports wgpu's internal live-object accounting.
30///
31/// All values are zero unless the `counters` feature is enabled.
32#[derive(Clone, Copy, Debug, Default)]
33pub struct WgpuCounters {
34 /// `enabled` indicates whether the `counters` feature is active.
35 pub enabled: bool,
36 /// `buffers` is the number of live wgpu buffers.
37 pub buffers: i64,
38 /// `textures` is the number of live wgpu textures.
39 pub textures: i64,
40 /// `bind_groups` is the number of live wgpu bind groups.
41 pub bind_groups: i64,
42 /// `buffer_memory` is wgpu's reported buffer memory in bytes.
43 pub buffer_memory: i64,
44 /// `texture_memory` is wgpu's reported texture memory in bytes.
45 pub texture_memory: i64,
46}
47
48/// `MemoryReport` summarizes resources retained between frames.
49///
50/// Pool byte counts are estimates derived from resource descriptors. `wgpu`
51/// contains separate internal counters when that feature is enabled.
52#[derive(Clone, Copy, Debug, Default)]
53pub struct MemoryReport {
54 /// `images` reports live uploaded images, including mip levels.
55 pub images: PoolReport,
56 /// `atlas` reports `[mask and SDF, color]` glyph-atlas families.
57 pub atlas: [AtlasReport; 2],
58 /// `targets` reports pooled layer, snapshot, filter, and scratch targets.
59 pub targets: PoolReport,
60 /// `host_buffer` reports transient upload-buffer blocks.
61 pub host_buffer: PoolReport,
62 /// `contours` reports cached flattened path contours.
63 pub contours: PoolReport,
64 /// `glyph_paths` reports cached vector glyph paths.
65 pub glyph_paths: PoolReport,
66 /// `ramps` reports cached gradient-ramp textures.
67 pub ramps: PoolReport,
68 /// `raster_cache` reports cached display-list textures.
69 pub raster_cache: PoolReport,
70 /// `wgpu` contains wgpu's internal object and memory counters.
71 pub wgpu: WgpuCounters,
72}
73
74impl MemoryReport {
75 /// `total_bytes` returns the sum of Valo's estimated retained memory.
76 ///
77 /// The separate wgpu counters are excluded.
78 pub fn total_bytes(&self) -> u64 {
79 self.images.bytes
80 + self.atlas.iter().map(|a| a.bytes).sum::<u64>()
81 + self.targets.bytes
82 + self.raster_cache.bytes
83 + self.host_buffer.bytes
84 + self.contours.bytes
85 + self.glyph_paths.bytes
86 + self.ramps.bytes
87 }
88}
89
90pub(crate) fn wgpu_counters(device: &wgpu::Device) -> WgpuCounters {
91 let hal = device.get_internal_counters().hal;
92 WgpuCounters {
93 enabled: cfg!(feature = "counters"),
94 buffers: hal.buffers.read() as i64,
95 textures: hal.textures.read() as i64,
96 bind_groups: hal.bind_groups.read() as i64,
97 buffer_memory: hal.buffer_memory.read() as i64,
98 texture_memory: hal.texture_memory.read() as i64,
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::{AtlasReport, MemoryReport, PoolReport, WgpuCounters};
105
106 #[test]
107 fn total_bytes_includes_every_valo_pool() {
108 let report = MemoryReport {
109 images: pool(1),
110 atlas: [atlas(2), atlas(3)],
111 targets: pool(4),
112 host_buffer: pool(5),
113 contours: pool(6),
114 glyph_paths: pool(7),
115 ramps: pool(8),
116 raster_cache: pool(9),
117 wgpu: WgpuCounters {
118 buffer_memory: 1_000,
119 texture_memory: 2_000,
120 ..Default::default()
121 },
122 };
123
124 assert_eq!(report.total_bytes(), 45);
125 }
126
127 fn pool(bytes: u64) -> PoolReport {
128 PoolReport { count: 1, bytes }
129 }
130
131 fn atlas(bytes: u64) -> AtlasReport {
132 AtlasReport {
133 pages: 1,
134 bytes,
135 entries: 1,
136 }
137 }
138}