mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-24 09:57:08 -06:00
GPU memory on top of #5234: memory_budget takes the card's memory (vram) and the GPU Memory value; the document's pixels are charged unless the card's own memory is known; a set GPU Memory is capped at the card's share; benches use video_memory
This commit is contained in:
@@ -586,7 +586,7 @@ fn full_canvas_layer_scenarios(b: &mut Bench, sz: &Sizes) {
|
||||
allowance,
|
||||
pixels,
|
||||
photocraft_ui_egui::gpu_canvas::physical_memory(),
|
||||
g.dedicated_memory(),
|
||||
g.video_memory(),
|
||||
0,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -303,12 +303,6 @@ impl GpuCanvas {
|
||||
Some((c.resident_bytes(), c.fx_cache_bytes().saturating_add(usize::try_from(c.composite_cache_bytes()).unwrap_or(usize::MAX))))
|
||||
}
|
||||
|
||||
/// Whether the adapter has memory of its own (a discrete card): the document's pixels and
|
||||
/// History don't share it ([`memory_budget`]).
|
||||
pub fn dedicated_memory(&self) -> bool {
|
||||
self.rs.adapter.get_info().device_type == wgpu::DeviceType::DiscreteGpu
|
||||
}
|
||||
|
||||
/// Whether `doc`'s layers fit the budget as it now stands, measured without a refresh (a GPU
|
||||
/// Memory change shows in the status bar at once). `None` before the compositor exists.
|
||||
pub fn measure_fit(&self, doc: &photocraft_doc::Document) -> Option<LayerFit> {
|
||||
@@ -2425,13 +2419,14 @@ mod tests {
|
||||
fn gpu_budgets_fit_a_discrete_gpus_own_memory() {
|
||||
const G: u64 = 1 << 30;
|
||||
let (ram, vram) = (Some(64 * G), Some(8 * G));
|
||||
assert_eq!(memory_budget(64 * G, 3 * G, ram, vram), 3 * G);
|
||||
assert_eq!(memory_budget(64 * G, 3 * G, ram, vram, 0), 3 * G);
|
||||
assert_eq!(canvas_budget(ram, vram), 3 * G);
|
||||
assert!(memory_budget(64 * G, 0, ram, vram) + canvas_budget(ram, vram) <= 6 * G, "a quarter of the card stays free");
|
||||
// A card larger than a quarter of RAM changes nothing; a tiny one keeps the floor.
|
||||
assert_eq!(memory_budget(8 * G, 3 * G, Some(48 * G), Some(24 * G)), 5 * G);
|
||||
assert!(memory_budget(64 * G, 0, ram, vram, 0) + canvas_budget(ram, vram) <= 6 * G, "a quarter of the card stays free");
|
||||
// A card larger than a quarter of RAM caps nothing (its own memory isn't charged for the
|
||||
// document's 3 GB); a tiny one keeps the floor.
|
||||
assert_eq!(memory_budget(8 * G, 3 * G, Some(48 * G), Some(24 * G), 0), 8 * G);
|
||||
assert_eq!(canvas_budget(Some(16 * G), Some(24 * G)), 4 * G);
|
||||
assert_eq!(memory_budget(64 * G, 0, ram, Some(G)), MIN_GPU_BUDGET);
|
||||
assert_eq!(memory_budget(64 * G, 0, ram, Some(G), 0), MIN_GPU_BUDGET);
|
||||
assert_eq!(canvas_budget(ram, Some(G)), MIN_GPU_BUDGET);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ Generated by `cargo xtask scorecard` from `perf/budgets.toml`, `perf/baseline.js
|
||||
| [Performance](#performance) | 3 | 22 | 24 | 58 scenarios: 3 within budget, 22 over budget or failing, 9 tracked only, 19 not run, 5 not measurable yet (baseline 2026-10-05) |
|
||||
| [File compatibility](#file-compatibility) | 7 | 14 | 6 | io corpus: oracle ≥ 148/170, round trip ≥ 169/170; psd-tools corpus: oracle ≥ 249/309, round trip ≥ 308/309; photoshop oracles: oracle ≥ 188/256, round trip ≥ 258/256 |
|
||||
| [Tools](#tools) | 33 | 11 | 0 | |
|
||||
| [Workspace and UI](#workspace-and-ui) | 13 | 6 | 4 | settings that do nothing: 26 of 167 (target 0) |
|
||||
| [Workspace and UI](#workspace-and-ui) | 13 | 6 | 4 | settings that do nothing: 26 of 168 (target 0) |
|
||||
| [Type](#type) | 4 | 3 | 2 | |
|
||||
| [Automation](#automation) | 5 | 2 | 4 | 631 of 631 menu items live (100.0%) |
|
||||
| [Reliability](#reliability) | 5 | 2 | 0 | never-crash lints on 29 of 29 crates; panic_hunt present |
|
||||
@@ -179,7 +179,7 @@ Corpus floors (`crates/io/tests/corpus.rs`): the enforced minimums; the corpus t
|
||||
|
||||
## Workspace and UI
|
||||
|
||||
**Settings that do nothing: 26 of 167** (target 0, #204). Counted by the prefs audit (`xtask/src/scorecard.rs`): a `Preferences` field counts as read when code outside the prefs model (`prefs.rs` except its `impl Session` blocks; tests excluded; the schema-driven dialog never names a field) accesses `section.field`, or `.section` and `.field` in the same file, or calls a section method that reads `self.field`. It is a heuristic lower bound: a generic name can look read when it isn't.
|
||||
**Settings that do nothing: 26 of 168** (target 0, #204). Counted by the prefs audit (`xtask/src/scorecard.rs`): a `Preferences` field counts as read when code outside the prefs model (`prefs.rs` except its `impl Session` blocks; tests excluded; the schema-driven dialog never names a field) accesses `section.field`, or `.section` and `.field` in the same file, or calls a section method that reads `self.field`. It is a heuristic lower bound: a generic name can look read when it isn't.
|
||||
|
||||
Unread: `general.color_picker`, `general.animated_zoom`, `general.zoom_resizes_windows`, `workspace.auto_show_hidden_panels`, `workspace.enable_floating_document_window_docking`, `file_handling.save_in_background`, `performance.cache_levels`, `performance.legacy_compositing`, `scratch_disks.disks`, `units_and_rulers.column_width`, `units_and_rulers.gutter`, `plug_ins.show_extension_panels`, `plug_ins.allow_scripts_to_connect`, `plug_ins.generator_enabled`, `type_.text_engine`, `type_.recent_fonts`, `enhanced_controls.scrubby_slider_acceleration`, `enhanced_controls.touch_gestures`, `raw_defaults.color_space`, `raw_defaults.bit_depth`, `raw_defaults.resolution`, `raw_defaults.sharpen_for`, `raw_defaults.open_as_smart_object`, `raw_defaults.apply_auto_tone`, `integrations.allow_agent_control`, `integrations.control_port`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user