Skip to content

Commit

Permalink
Pass vertex data as storage buffer and use it instead of the instance…
Browse files Browse the repository at this point in the history
… input
  • Loading branch information
abey79 committed Dec 23, 2024
1 parent cc44dbb commit 33f7713
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 39 deletions.
25 changes: 10 additions & 15 deletions crates/vsvg-viewer/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ impl LayerPainters {
if let Some(line_painter_data) = layer_data.line_painter_data() {
self.line_painter.draw(
render_pass,
&render_objects.camera_bind_group,
render_objects,
//&render_objects.camera_bind_group,
line_painter_data,
);
}
Expand All @@ -163,13 +164,13 @@ impl LayerPainters {
if let Some(bezier_handles_painter_data) = layer_data.bezier_handles_painter_data() {
self.bezier_handles_point_painter.draw(
render_pass,
&render_objects.camera_bind_group,
render_objects,
&bezier_handles_painter_data.point_painter_data,
);

self.bezier_handles_line_painter.draw(
render_pass,
&render_objects.camera_bind_group,
render_objects,
&bezier_handles_painter_data.line_painter_data,
);
}
Expand All @@ -180,19 +181,16 @@ impl LayerPainters {
{
self.display_vertices_painter.draw(
render_pass,
&render_objects.camera_bind_group,
render_objects,
display_vertices_painter_data,
);
}
}

if display_options.show_pen_up {
if let Some(pen_up_painter_data) = layer_data.pen_up_painter_data() {
self.pen_up_painter.draw(
render_pass,
&render_objects.camera_bind_group,
pen_up_painter_data,
);
self.pen_up_painter
.draw(render_pass, render_objects, pen_up_painter_data);
}
}
}
Expand All @@ -201,7 +199,7 @@ impl LayerPainters {
/// wgpu-related objects used by the engine.
///
/// They are grouped in a separate structure, so they can be provided to painters during engine
/// initialisation.
/// initialization.
pub(crate) struct EngineRenderObjects {
pub(crate) device: Arc<Device>,
pub(crate) camera_buffer: Buffer,
Expand Down Expand Up @@ -369,11 +367,8 @@ impl Engine {
vsvg::trace_function!();

if let Some(page_size_painter_data) = &self.page_size_painter_data {
self.page_size_painter.draw(
render_pass,
&self.render_objects.camera_bind_group,
page_size_painter_data,
);
self.page_size_painter
.draw(render_pass, &self.render_objects, page_size_painter_data);
}

let mut viewer_options = self.viewer_options.lock().unwrap();
Expand Down
4 changes: 2 additions & 2 deletions crates/vsvg-viewer/src/painters/basic_painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ impl Painter for BasicPainter {
fn draw(
&self,
rpass: &mut RenderPass<'static>,
camera_bind_group: &wgpu::BindGroup,
render_objects: &EngineRenderObjects,
data: &Self::Data,
) {
// `Buffer::slice(..)` panics for empty buffers in wgpu 23+
Expand All @@ -147,7 +147,7 @@ impl Painter for BasicPainter {
}

rpass.set_pipeline(&self.render_pipeline);
rpass.set_bind_group(0, camera_bind_group, &[]);
rpass.set_bind_group(0, &render_objects.camera_bind_group, &[]);
rpass.set_vertex_buffer(0, data.vertex_buffer.slice(..));
rpass.draw(0..data.vertex_count, 0..1);
}
Expand Down
53 changes: 48 additions & 5 deletions crates/vsvg-viewer/src/painters/line_painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ impl LinePainterData {
.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Point instance buffer"),
contents: bytemuck::cast_slice(vertices.as_slice()),
usage: wgpu::BufferUsages::VERTEX,
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::STORAGE,
});

// prepare color buffer
Expand Down Expand Up @@ -282,6 +282,7 @@ impl LinePainterData {
///
/// See module documentation for details.
pub(crate) struct LinePainter {
points_bind_group_layout: wgpu::BindGroupLayout,
render_pipeline: RenderPipeline,
}

Expand Down Expand Up @@ -320,6 +321,23 @@ impl LinePainter {
attributes: &vertex_attrib_color_width,
});

let points_bind_group_layout =
render_objects
.device
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::VERTEX,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Storage { read_only: true },
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
}],
label: Some("point_bind_group_layout"),
});

let shader = render_objects
.device
.create_shader_module(include_wgsl!("../shaders/line.wgsl"));
Expand All @@ -329,7 +347,10 @@ impl LinePainter {
.device
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: None,
bind_group_layouts: &[&render_objects.camera_bind_group_layout],
bind_group_layouts: &[
&render_objects.camera_bind_group_layout,
&points_bind_group_layout,
],
push_constant_ranges: &[],
});

Expand Down Expand Up @@ -379,7 +400,12 @@ impl LinePainter {
cache: None,
});

Self { render_pipeline }
/////////

Self {
points_bind_group_layout,
render_pipeline,
}
}
}

Expand All @@ -389,7 +415,7 @@ impl Painter for LinePainter {
fn draw(
&self,
rpass: &mut RenderPass<'static>,
camera_bind_group: &wgpu::BindGroup,
render_objects: &EngineRenderObjects,
data: &LinePainterData,
) {
// `Buffer::slice(..)` panics for empty buffers in wgpu 23+
Expand All @@ -398,7 +424,24 @@ impl Painter for LinePainter {
}

rpass.set_pipeline(&self.render_pipeline);
rpass.set_bind_group(0, camera_bind_group, &[]);
rpass.set_bind_group(0, &render_objects.camera_bind_group, &[]);

//////
//TODO: this could be done once

let points_bind_group =
render_objects
.device
.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &self.points_bind_group_layout,
entries: &[wgpu::BindGroupEntry {
binding: 0,
resource: data.points_buffer.as_entire_binding(),
}],
label: Some("point_bind_group"),
});

rpass.set_bind_group(1, &points_bind_group, &[]);

let offset = size_of::<Vertex>() as u64;
rpass.set_vertex_buffer(0, data.points_buffer.slice(..));
Expand Down
3 changes: 2 additions & 1 deletion crates/vsvg-viewer/src/painters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod point_painter;
use vsvg::Point;
use wgpu::RenderPass;

use crate::engine::EngineRenderObjects;
pub(crate) use basic_painter::{BasicPainter, BasicPainterData};
pub(crate) use line_painter::{LineDisplayOptions, LinePainter, LinePainterData};
pub(crate) use page_size_painter::{PageSizePainter, PageSizePainterData};
Expand All @@ -17,7 +18,7 @@ pub(crate) trait Painter {
fn draw(
&self,
rpass: &mut RenderPass<'static>,
camera_bind_group: &wgpu::BindGroup,
render_objects: &EngineRenderObjects,
data: &Self::Data,
);
}
Expand Down
10 changes: 5 additions & 5 deletions crates/vsvg-viewer/src/painters/page_size_painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::engine::{
};
use crate::painters::{BasicPainter, BasicPainterData, Painter};
use vsvg::PageSize;
use wgpu::{BindGroup, RenderPass};
use wgpu::RenderPass;

pub(crate) struct PageSizePainterData {
background: BasicPainterData,
Expand Down Expand Up @@ -64,14 +64,14 @@ impl Painter for PageSizePainter {
fn draw(
&self,
rpass: &mut RenderPass<'static>,
camera_bind_group: &BindGroup,
render_objects: &EngineRenderObjects,
data: &Self::Data,
) {
self.background_and_shadow_painter
.draw(rpass, camera_bind_group, &data.shadow);
.draw(rpass, render_objects, &data.shadow);
self.background_and_shadow_painter
.draw(rpass, camera_bind_group, &data.background);
.draw(rpass, render_objects, &data.background);
self.border_painter
.draw(rpass, camera_bind_group, &data.border);
.draw(rpass, render_objects, &data.border);
}
}
4 changes: 2 additions & 2 deletions crates/vsvg-viewer/src/painters/point_painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl Painter for PointPainter {
fn draw(
&self,
rpass: &mut RenderPass<'static>,
camera_bind_group: &wgpu::BindGroup,
render_objects: &EngineRenderObjects,
data: &Self::Data,
) {
// `Buffer::slice(..)` panics for empty buffers in wgpu 23+
Expand All @@ -149,7 +149,7 @@ impl Painter for PointPainter {
}

rpass.set_pipeline(&self.render_pipeline);
rpass.set_bind_group(0, camera_bind_group, &[]);
rpass.set_bind_group(0, &render_objects.camera_bind_group, &[]);
rpass.set_vertex_buffer(0, data.instance_buffer.slice(..));
rpass.draw(0..4, 0..data.instance_count);
}
Expand Down
31 changes: 22 additions & 9 deletions crates/vsvg-viewer/src/shaders/line.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ struct CameraUniform {
};

@group(0) @binding(0) var<uniform> camera: CameraUniform;
@group(1) @binding(0) var<storage, read> points: array<vec2<f32>>;

struct InstanceInput {
@location(0) p0: vec2<f32>,
Expand Down Expand Up @@ -79,27 +80,39 @@ fn vs_main(

let w2 = instance.width/2. + (camera.anti_alias / camera.scale) / 2.;

let d = distance(instance.p1, instance.p2);
let v = normalize(instance.p2 - instance.p1);

// let p0 = instance.p0;
// let p1 = instance.p1;
// let p2 = instance.p2;
// let p3 = instance.p3;

let p0 = points[in_instance_index + 0];
let p1 = points[in_instance_index + 1];
let p2 = points[in_instance_index + 2];
let p3 = points[in_instance_index + 3];


let d = distance(p1, p2);
let v = normalize(p2 - p1);
let n = vec2<f32>(-v.y, v.x);

var vertex: vec2<f32>;
var tex_coords: vec2<f32>;
switch (in_vertex_index) {
case 0u: {
vertex = instance.p1 + w2 * (-v - n);
vertex = p1 + w2 * (-v - n);
tex_coords = vec2<f32>(-w2, -w2);
}
case 1u: {
vertex = instance.p1 + w2 * (-v + n);
vertex = p1 + w2 * (-v + n);
tex_coords = vec2<f32>(-w2, w2);
}
case 2u: {
vertex = instance.p2 + w2 * (v - n);
vertex = p2 + w2 * (v - n);
tex_coords = vec2<f32>(d + w2, -w2);
}
default: { // case 3u
vertex = instance.p2 + w2 * (v + n);
vertex = p2 + w2 * (v + n);
tex_coords = vec2<f32>(d + w2, w2);
}
}
Expand All @@ -117,9 +130,9 @@ fn vs_main(
out.distance = d;

// compute miter points
let critical_length_mid = length(instance.p2 - instance.p1 + w2 * n);
let m0 = compute_miter(instance.p0, instance.p1, n, critical_length_mid, w2);
let m2 = compute_miter(instance.p2, instance.p3, n, critical_length_mid, w2);
let critical_length_mid = length(p2 - p1 + w2 * n);
let m0 = compute_miter(p0, p1, n, critical_length_mid, w2);
let m2 = compute_miter(p2, p3, n, critical_length_mid, w2);
out.color = color;
out.width = instance.width;

Expand Down

0 comments on commit 33f7713

Please sign in to comment.