forked from 1b-agent/opencadstudio-upstream
perf(render): in-place GPU wire arena for move/edit (phase 4, OCS_WIRE_GPU_PATCH)
On a geometry edit the resident set gets a fresh content id, so the batched wire path (build_wire_buffers) re-emits and re-uploads EVERY wire instance — the whole buffer even when one line moved. Behind the OCS_WIRE_GPU_PATCH flag (default off, native only), add a persistent per-entity instance arena: one long-lived VERTEX|COPY_DST instance buffer + its WireConst storage, with a per-entity slab table. An in-place edit (move / rotate / scale / colour — same segment count) becomes a queue.write_buffer of just that entity`s slab. Scope is deliberately IN-PLACE ONLY. draw_depth_map normalises each entity`s draw-order z-bias by the block`s entity count, so an Add or Remove re-scales EVERY entity`s z-bias — which a per-slab patch can`t honour — and a segment-count change relocates the entity. patch() returns false for any of those (and for mesh-edge / scissored sets), and the caller falls back to the identical full batched rebuild, so correctness never rides on the fast path. An adversarial review of an earlier append/tombstone design surfaced exactly these draw-order hazards; restricting to in-place removes them while keeping the common interactive-edit win. The Scene hands the changed handles to the arena via model_wire_gpu_patch, recorded by try_resident_patch for the Model block and matched by content id in prepare(); scissored paper viewports and mixed 2D/3D sets keep the batched path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
0907d2912d
commit
38c8583d27
5 files changed
+398
-6
No files matched your search
@@ -10,6 +10,11 @@ pub mod mesh_gpu;
|
||||
pub mod text_gpu;
|
||||
pub mod uniforms;
|
||||
pub mod viewcube;
|
||||
/// Persistent per-entity wire instance arena (native), enabled by
|
||||
/// `OCS_WIRE_GPU_PATCH` — patches one entity's slab via `write_buffer` instead
|
||||
/// of re-uploading the whole wire set on an edit.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub mod wire_arena;
|
||||
pub mod wire_gpu;
|
||||
|
||||
use iced::wgpu;
|
||||
@@ -44,7 +49,7 @@ pub struct Pipeline {
|
||||
/// xray pipelines). `Some` on native; `None` on web (fat instance, no
|
||||
/// storage). Passed to `WireGpu::from_run` / `from_batch` so they can build
|
||||
/// each batch's per-wire bind group.
|
||||
wire_const_bgl: Option<wgpu::BindGroupLayout>,
|
||||
pub(crate) wire_const_bgl: Option<wgpu::BindGroupLayout>,
|
||||
wipeout_pipeline: wgpu::RenderPipeline,
|
||||
/// Phase 4-B — single-draw batched hatch pipeline. Per-instance
|
||||
/// data lives in storage buffers; one draw call covers every
|
||||
@@ -144,6 +149,14 @@ pub struct Pipeline {
|
||||
/// their camera uniforms + scissor stay per-slot, only the geometry is
|
||||
/// deduplicated. Never mutated in place, only reassigned on content change.
|
||||
pub(crate) gpu_wires: std::sync::Arc<Vec<WireGpu>>,
|
||||
/// Persistent per-entity wire instance arena (native, `OCS_WIRE_GPU_PATCH`).
|
||||
/// When active, `gpu_wires` is a thin wrapper over this arena's buffers and an
|
||||
/// edit patches one entity's slab in place instead of rebuilding every wire.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) wire_arena: Option<wire_arena::WireArena>,
|
||||
/// The Model content id `wire_arena` currently mirrors (`u64::MAX` = none).
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) wire_arena_id: u64,
|
||||
/// Pixel scissor rects [x, y, w, h] for viewport-clipped wires. Recomputed each frame.
|
||||
wire_pixel_scissors: Vec<Option<[u32; 4]>>,
|
||||
/// Ghost copies (25% alpha) of selected wires for the X-ray depth pass.
|
||||
@@ -1304,6 +1317,10 @@ impl Pipeline {
|
||||
blit_uniform_buffer,
|
||||
surface_format: format,
|
||||
gpu_wires: std::sync::Arc::new(vec![]),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wire_arena: None,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wire_arena_id: u64::MAX,
|
||||
wire_pixel_scissors: vec![],
|
||||
gpu_selected_wires: vec![],
|
||||
gpu_preview_wires: vec![],
|
||||
|
||||
Reference in new issue
Block a user