perf: speed large drawing workflows
This commit is contained in:
parent
97be4fefaa
commit
39449ec684
10 changed files with 700 additions and 195 deletions
|
|
@ -163,6 +163,14 @@ pub struct Pipeline {
|
|||
/// both patch incrementally. Shares `wire_arena_id`.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) wire_arena_mesh: Option<wire_arena::WireArena>,
|
||||
/// Chunked resident buffers for whichever arena partition exceeded one
|
||||
/// GPU buffer. `Some(false)` = regular wires, `Some(true)` = mesh edges.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) wire_arena_fallback: std::sync::Arc<Vec<WireGpu>>,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) wire_arena_fallback_kind: Option<bool>,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) wire_arena_fallback_handles: rustc_hash::FxHashSet<acadrust::Handle>,
|
||||
/// The Model content id both arenas currently mirror (`u64::MAX` = none).
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) wire_arena_id: u64,
|
||||
|
|
@ -1455,6 +1463,12 @@ impl Pipeline {
|
|||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wire_arena_mesh: None,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wire_arena_fallback: std::sync::Arc::new(Vec::new()),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wire_arena_fallback_kind: None,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wire_arena_fallback_handles: rustc_hash::FxHashSet::default(),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wire_arena_id: u64::MAX,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wire_cull_key: (u64::MAX, u64::MAX, 0, 0),
|
||||
|
|
|
|||
|
|
@ -282,6 +282,7 @@ impl WirePipelineMode {
|
|||
|
||||
// ── GPU handle ────────────────────────────────────────────────────────────
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WireGpu {
|
||||
pub instance_buffer: wgpu::Buffer,
|
||||
/// First instance in a shared arena buffer. Standalone buffers start at 0.
|
||||
|
|
@ -609,6 +610,55 @@ fn build_const_bind_group(
|
|||
}
|
||||
|
||||
impl WireGpu {
|
||||
/// Native-only equivalent of [`from_run`] for an already partitioned set
|
||||
/// of borrowed wires. Used when one arena partition exceeds the 256 MB
|
||||
/// buffer limit: the compatible partition stays patchable while only the
|
||||
/// oversized side uses chunked resident buffers.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn from_run_refs(
|
||||
device: &wgpu::Device,
|
||||
wires: &[&WireModel],
|
||||
depth_map: &rustc_hash::FxHashMap<u64, [f32; 2]>,
|
||||
mesh_edge: bool,
|
||||
const_bgl: &wgpu::BindGroupLayout,
|
||||
) -> Vec<Self> {
|
||||
const MAX_INSTANCES: usize =
|
||||
268_435_456 / std::mem::size_of::<WireInstance>();
|
||||
use crate::par::prelude::*;
|
||||
let per: Vec<(Vec<WireInstance>, WireConst)> = wires
|
||||
.par_iter()
|
||||
.enumerate()
|
||||
.map(|(idx, &wire)| {
|
||||
let depth = if mesh_edge {
|
||||
0.0
|
||||
} else {
|
||||
wire_draw_depth(wire, depth_map)
|
||||
};
|
||||
emit_wire_native(wire, idx as u32, wire.color, depth)
|
||||
})
|
||||
.collect();
|
||||
let mut instances: Vec<WireInstance> =
|
||||
Vec::with_capacity(per.iter().map(|(items, _)| items.len()).sum());
|
||||
let mut consts = Vec::with_capacity(per.len());
|
||||
for (mut items, constant) in per {
|
||||
instances.append(&mut items);
|
||||
consts.push(constant);
|
||||
}
|
||||
if instances.is_empty() {
|
||||
return Vec::new();
|
||||
}
|
||||
let bind_group = build_const_bind_group(device, const_bgl, &consts);
|
||||
instances
|
||||
.chunks(MAX_INSTANCES)
|
||||
.map(|chunk| Self {
|
||||
instance_buffer: instance_buffer_mapped(device, "wire.run.hybrid.ibuf", chunk),
|
||||
first_instance: 0,
|
||||
instance_count: chunk.len() as u32,
|
||||
is_3d_mesh_edge: mesh_edge,
|
||||
const_bind_group: Some(bind_group.clone()),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Merge a run of WireModels that share scissor + mesh-edge state into one
|
||||
/// (or, past the 256 MB GPU limit, a few) instance buffer(s), then stamp
|
||||
|
|
|
|||
Loading…
Reference in a new issue