perf(wire): switch wire pipeline to instanced rendering
Step 3 of the wire pipeline cold-open optimization plan — the biggest single lever. Each segment used to upload as 6 vertices × 96 B = 576 B with the segment payload (pos_a/pos_b/color/half_width/distance/pattern_length/pat0/pat1) duplicated across all six corners of the quad. Wire pipeline now uploads one INSTANCE per segment (88 B) and the vertex shader derives `which_end` and `side` from `@builtin(vertex_index)` against a 6-entry corner table. Net effect on cold open: ~6.5× less wire vertex memory and PCIe upload, plus a smaller Vec to allocate and copy on the CPU side. Wire instance attributes also collapse distance_a / distance_b into a single mix() inside the vertex shader, so per-segment distance still interpolates correctly for the GPU-side linetype dash test. Touches the wire, wire_xray, and face3d-edges draw passes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
0ad7af7742
commit
4b4f5c94cd
3 changed files with 123 additions and 133 deletions
|
|
@ -158,7 +158,7 @@ impl Pipeline {
|
|||
vertex: wgpu::VertexState {
|
||||
module: &wire_shader,
|
||||
entry_point: Some("vs_main"),
|
||||
buffers: &[wire_gpu::WireVertex::layout()],
|
||||
buffers: &[wire_gpu::WireInstance::layout()],
|
||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||
},
|
||||
primitive: wgpu::PrimitiveState {
|
||||
|
|
@ -201,7 +201,7 @@ impl Pipeline {
|
|||
vertex: wgpu::VertexState {
|
||||
module: &wire_shader,
|
||||
entry_point: Some("vs_main"),
|
||||
buffers: &[wire_gpu::WireVertex::layout()],
|
||||
buffers: &[wire_gpu::WireInstance::layout()],
|
||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||
},
|
||||
primitive: wgpu::PrimitiveState {
|
||||
|
|
@ -1073,9 +1073,9 @@ impl Pipeline {
|
|||
pass.set_pipeline(&self.wire_pipeline);
|
||||
pass.set_bind_group(0, &self.uniform_bind_group, &[]);
|
||||
for edges in &self.gpu_face3d_edges {
|
||||
if edges.vertex_count >= 6 {
|
||||
pass.set_vertex_buffer(0, edges.vertex_buffer.slice(..));
|
||||
pass.draw(0..edges.vertex_count, 0..1);
|
||||
if edges.instance_count > 0 {
|
||||
pass.set_vertex_buffer(0, edges.instance_buffer.slice(..));
|
||||
pass.draw(0..6, 0..edges.instance_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1109,7 +1109,7 @@ impl Pipeline {
|
|||
pass.set_bind_group(0, &self.uniform_bind_group, &[]);
|
||||
let mut scissor_active = false;
|
||||
for (i, wire) in self.gpu_wires.iter().enumerate() {
|
||||
if wire.vertex_count < 6 {
|
||||
if wire.instance_count == 0 {
|
||||
continue;
|
||||
}
|
||||
match self.wire_pixel_scissors.get(i) {
|
||||
|
|
@ -1123,8 +1123,8 @@ impl Pipeline {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
pass.set_vertex_buffer(0, wire.vertex_buffer.slice(..));
|
||||
pass.draw(0..wire.vertex_count, 0..1);
|
||||
pass.set_vertex_buffer(0, wire.instance_buffer.slice(..));
|
||||
pass.draw(0..6, 0..wire.instance_count);
|
||||
}
|
||||
if scissor_active {
|
||||
pass.set_scissor_rect(0, 0, vp.width, vp.height);
|
||||
|
|
@ -1213,9 +1213,9 @@ impl Pipeline {
|
|||
pass.set_pipeline(&self.wire_xray_pipeline);
|
||||
pass.set_bind_group(0, &self.uniform_bind_group, &[]);
|
||||
for wire in &self.gpu_selected_wires {
|
||||
if wire.vertex_count >= 6 {
|
||||
pass.set_vertex_buffer(0, wire.vertex_buffer.slice(..));
|
||||
pass.draw(0..wire.vertex_count, 0..1);
|
||||
if wire.instance_count > 0 {
|
||||
pass.set_vertex_buffer(0, wire.instance_buffer.slice(..));
|
||||
pass.draw(0..6, 0..wire.instance_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue