Merge pull request #1076 from mechpanos/pr/skip-partition-on-patch

This commit is contained in:
Hakan Seven committed 2026-09-08 17:17:59 +03:00
commit 2b510c1a1e
4 files changed
+256 -26

No files matched your search

+94 -25
View File
@@ -149,6 +149,9 @@ pub struct ViewportData {
/// by the wire / face3d pipelines as a clip-z bias. WireModels carry no
/// depth field (84 construction sites); the bias is looked up by handle
/// at GPU-upload time from this map instead.
/// See `Scene::draw_depth_generation`. Cached uploads that bake a depth are
/// only reusable while this is unchanged.
pub(in crate::scene) draw_depth_generation: u64,
pub(in crate::scene) draw_depths:
std::sync::Weak<rustc_hash::FxHashMap<u64, [f32; 2]>>,
pub(in crate::scene) hatches: Arc<Vec<HatchModel>>,
@@ -839,31 +842,96 @@ impl shader::Primitive for Primitive {
gpus.extend(arena.wire_gpus());
}
inner.gpu_wires = std::sync::Arc::new(gpus);
let partitioned =
wire_arena::partition_wires(&vp_wires, &draw_depths);
inner.gpu_block_wires = std::sync::Arc::new(
inner.upload_block_wires(
device,
queue,
&partitioned.instanced,
&draw_depths,
&mut pipeline.block_geometry,
),
);
inner.gpu_circles = std::sync::Arc::new(
inner.upload_circles_from_instances(
device,
queue,
&partitioned.circle_instances,
),
);
inner.gpu_ellipses = std::sync::Arc::new(
inner.upload_ellipses_from_instances(
device,
queue,
&partitioned.ellipse_instances,
),
);
// A one-entity patch costs 73 ms in this block, and the
// three steps below are all O(resident set) rather than
// O(changes). Which of them dominates decides the fix.
// The partition walks the whole resident set, and on
// a patch it almost always produces the three uploads it
// produced last frame. Skip it when no changed entity
// feeds them and none did before.
//
// Safe because adding an entity does not disturb any
// other entity's draw depth: `inserted_draw_depth_label`
// allocates into the reserved label gap rather than
// renumbering, so instances already uploaded stay right.
let analytical_untouched = _patched
&& inner.partition_depth_generation == vp.draw_depth_generation
&& patch.is_some_and(|patch| {
patch.changes.iter().all(|(handle, _)| {
!inner.partition_contributors.contains(handle)
&& !patch.runs.get(handle).is_some_and(|run| {
run.iter()
.any(wire_arena::feeds_analytical_uploads)
})
})
});
let t_part = _perf.then(iced::time::Instant::now);
let partitioned = (!analytical_untouched)
.then(|| wire_arena::partition_wires(&vp_wires, &draw_depths));
let part_ms = t_part
.map_or(0.0, |t| t.elapsed().as_secs_f64() * 1000.0);
let t_blk = _perf.then(iced::time::Instant::now);
let mut blk_ms = 0.0f64;
let mut curve_ms = 0.0f64;
// `None` means the three uploads this slot holds are
// still the answer, so they are left alone.
if let Some(partitioned) = &partitioned {
inner.gpu_block_wires = std::sync::Arc::new(
inner.upload_block_wires(
device,
queue,
&partitioned.instanced,
&draw_depths,
&mut pipeline.block_geometry,
),
);
blk_ms = t_blk
.map_or(0.0, |t| t.elapsed().as_secs_f64() * 1000.0);
let t_curve = _perf.then(iced::time::Instant::now);
inner.gpu_circles = std::sync::Arc::new(
inner.upload_circles_from_instances(
device,
queue,
&partitioned.circle_instances,
),
);
inner.gpu_ellipses = std::sync::Arc::new(
inner.upload_ellipses_from_instances(
device,
queue,
&partitioned.ellipse_instances,
),
);
inner
.partition_contributors
.clone_from(&partitioned.contributors);
inner.partition_depth_generation = vp.draw_depth_generation;
curve_ms = t_curve
.map_or(0.0, |t| t.elapsed().as_secs_f64() * 1000.0);
}
if _perf {
// Counts only when a partition produced them.
// Printing zeros on a skip reads as "no circles"
// rather than "not recomputed", which is the
// opposite of what the line is reporting.
match &partitioned {
Some(partitioned) => crate::perf_record!(
"[perf] arena-post partition={part_ms:.1}ms \
blocks={blk_ms:.1}ms curves={curve_ms:.1}ms skipped=false wires={} instanced={} \
circles={} ellipses={}",
vp_wires.len(),
partitioned.instanced.len(),
partitioned.circle_instances.len(),
partitioned.ellipse_instances.len(),
),
None => crate::perf_record!(
"[perf] arena-post skipped=true wires={} \
retained_contributors={}",
vp_wires.len(),
inner.partition_contributors.len(),
),
}
}
if _patched {
wire_arena::patch_handle_index(
&mut inner.wire_handle_index,
@@ -4239,6 +4307,7 @@ impl Scene {
face3d_wires,
text_verts,
preview_text_verts,
draw_depth_generation: self.draw_depth_generation(),
draw_depths: Arc::downgrade(&draw_depths),
hatches,
wipeout_hatches,