From 59ebdc4f9322e4d74ef538e731b6e180b0b24e18 Mon Sep 17 00:00:00 2001 From: Maximilian Ammann Date: Sat, 8 Jan 2022 11:15:43 +0100 Subject: [PATCH] Use u16 for indices --- src/render/state.rs | 11 +++++------ src/tesselation/misc.rs | 16 +++++++--------- src/tesselation/mod.rs | 39 ++++++++++++++++++++++++--------------- src/tesselation/tile.rs | 30 +++++++++++++++++------------- 4 files changed, 53 insertions(+), 43 deletions(-) diff --git a/src/render/state.rs b/src/render/state.rs index 3ab90366..80be1df9 100644 --- a/src/render/state.rs +++ b/src/render/state.rs @@ -39,7 +39,11 @@ impl Default for SceneParams { } } -const INDEX_FORMAT: wgpu::IndexFormat = wgpu::IndexFormat::Uint32; +const INDEX_FORMAT: wgpu::IndexFormat = wgpu::IndexFormat::Uint16; // Must match IndexDataType +const VERTEX_BUFFER_SIZE: BufferAddress = 1024 * 1024 * 16; +const INDICES_BUFFER_SIZE: BufferAddress = 1024 * 1024 * 16; +const TILE_META_COUNT: BufferAddress = 512; +const TILE_MASK_INSTANCE_COUNT: BufferAddress = 512; pub struct State { instance: wgpu::Instance, @@ -86,11 +90,6 @@ impl SceneParams { } } -const VERTEX_BUFFER_SIZE: BufferAddress = 1024 * 1024 * 32; -const INDICES_BUFFER_SIZE: BufferAddress = 1024 * 1024 * 32; -const TILE_META_COUNT: BufferAddress = 512; -const TILE_MASK_INSTANCE_COUNT: BufferAddress = 512; - impl State { pub async fn new(window: &Window) -> Self { let mut measure = Measure::time(); diff --git a/src/tesselation/misc.rs b/src/tesselation/misc.rs index 2636fd18..856c7c0c 100644 --- a/src/tesselation/misc.rs +++ b/src/tesselation/misc.rs @@ -14,7 +14,7 @@ use vector_tile::geometry::{Command, Geometry}; use vector_tile::tile::Tile; use crate::render::shader_ffi::GpuVertexUniform; -use crate::tesselation::{Tesselated, WithId, DEFAULT_TOLERANCE}; +use crate::tesselation::{IndexDataType, Tesselated, VertexConstructor, DEFAULT_TOLERANCE}; pub struct RustLogo(); @@ -25,8 +25,7 @@ impl< fn tesselate_stroke( &self, buffer: &mut VertexBuffers, - prim_id: u32, - ) -> Range { + ) -> Range { let mut stroke_tess = StrokeTessellator::new(); let initial_indices_count = buffer.indices.len(); @@ -40,18 +39,17 @@ impl< .tessellate_path( &rust_logo, &StrokeOptions::tolerance(DEFAULT_TOLERANCE), - &mut BuffersBuilder::new(buffer, WithId(prim_id)), + &mut BuffersBuilder::new(buffer, VertexConstructor()), ) .unwrap(); - initial_indices_count as u32..buffer.indices.len() as u32 + initial_indices_count as IndexDataType..buffer.indices.len() as IndexDataType } fn tesselate_fill( &self, buffer: &mut VertexBuffers, - prim_id: u32, - ) -> Range { + ) -> Range { let mut fill_tess = FillTessellator::new(); let initial_indices_count = buffer.indices.len(); @@ -66,10 +64,10 @@ impl< &rust_logo, &FillOptions::tolerance(DEFAULT_TOLERANCE) .with_fill_rule(lyon_path::FillRule::NonZero), - &mut BuffersBuilder::new(buffer, WithId(prim_id as u32)), + &mut BuffersBuilder::new(buffer, VertexConstructor()), ) .unwrap(); - initial_indices_count as u32..buffer.indices.len() as u32 + initial_indices_count as IndexDataType..buffer.indices.len() as IndexDataType } } diff --git a/src/tesselation/mod.rs b/src/tesselation/mod.rs index 8e448f72..b55e8e0d 100644 --- a/src/tesselation/mod.rs +++ b/src/tesselation/mod.rs @@ -9,46 +9,55 @@ use std::ops::Range; const DEFAULT_TOLERANCE: f32 = 0.02; -pub type IndexDataType = u32; // Must match INDEX_FORMAT +pub type IndexDataType = u16; // Must match INDEX_FORMAT pub trait Tesselated { fn tesselate_stroke( &self, buffer: &mut VertexBuffers, - prim_id: u32, - ) -> Range; + ) -> Range; fn tesselate_fill( &self, buffer: &mut VertexBuffers, - prim_id: u32, - ) -> Range; + ) -> Range; fn empty_range( &self, buffer: &mut VertexBuffers, - _prim_id: u32, - ) -> Range { - let initial_indices_count = buffer.indices.len() as u32; + ) -> Range { + let initial_indices_count = buffer.indices.len() as IndexDataType; initial_indices_count..initial_indices_count } } -/// This vertex constructor forwards the positions and normals provided by the -/// tessellators and add a shape id. -pub struct WithId(pub u32); +pub struct VertexConstructor(); -impl FillVertexConstructor for WithId { +impl FillVertexConstructor for VertexConstructor { fn new_vertex(&mut self, vertex: FillVertex) -> GpuVertexUniform { - GpuVertexUniform::new(vertex.position().to_array(), [0.0, 0.0], self.0) + GpuVertexUniform::new(vertex.position().to_array(), [0.0, 0.0]) } } -impl StrokeVertexConstructor for WithId { +impl StrokeVertexConstructor for VertexConstructor { fn new_vertex(&mut self, vertex: StrokeVertex) -> GpuVertexUniform { GpuVertexUniform::new( vertex.position_on_path().to_array(), vertex.normal().to_array(), - self.0, ) } } + +trait Align { + fn align_indices(&mut self); +} + +impl Align for VertexBuffers { + fn align_indices(&mut self) { + let alignment = wgpu::COPY_BUFFER_ALIGNMENT as usize / std::mem::size_of::(); + let padding = self.indices.len() % alignment; + if padding > 0 { + self.indices + .extend(std::iter::repeat(I::zeroed()).take(alignment - padding)); + } + } +} diff --git a/src/tesselation/tile.rs b/src/tesselation/tile.rs index 49f7b520..4f768ccc 100644 --- a/src/tesselation/tile.rs +++ b/src/tesselation/tile.rs @@ -1,3 +1,5 @@ +use std::ops::Range; + use lyon::lyon_tessellation::LineJoin; use lyon::tessellation; use lyon::tessellation::geometry_builder::MaxIndex; @@ -7,13 +9,12 @@ use lyon::tessellation::{ }; use lyon_path::builder::SvgPathBuilder; use lyon_path::Path; -use std::ops::Range; use vector_tile::geometry::{Command, Geometry}; use vector_tile::tile::Tile; use crate::render::shader_ffi::GpuVertexUniform; -use crate::tesselation::{Tesselated, WithId, DEFAULT_TOLERANCE}; +use crate::tesselation::{Align, IndexDataType, Tesselated, VertexConstructor, DEFAULT_TOLERANCE}; fn build_path(tile: &Tile, fill: bool) -> Path { let mut tile_builder = Path::builder().with_svg(); @@ -85,14 +86,16 @@ fn build_path(tile: &Tile, fill: bool) -> Path { } impl< - OutputIndex: std::ops::Add + std::convert::From + MaxIndex, + OutputIndex: std::ops::Add + + std::convert::From + + MaxIndex + + bytemuck::Pod, > Tesselated for Tile { fn tesselate_stroke( &self, buffer: &mut VertexBuffers, - prim_id: u32, - ) -> Range { + ) -> Range { let mut tesselator = StrokeTessellator::new(); let initial_indices_count = buffer.indices.len(); @@ -102,19 +105,20 @@ impl< tesselator .tessellate_path( &tile_path, - &StrokeOptions::default(), - &mut BuffersBuilder::new(buffer, WithId(prim_id)), + &StrokeOptions::tolerance(DEFAULT_TOLERANCE), + &mut BuffersBuilder::new(buffer, VertexConstructor()), ) .unwrap(); - initial_indices_count as u32..buffer.indices.len() as u32 + buffer.align_indices(); + + initial_indices_count as IndexDataType..buffer.indices.len() as IndexDataType } fn tesselate_fill( &self, buffer: &mut VertexBuffers, - prim_id: u32, - ) -> Range { + ) -> Range { let mut tesselator = FillTessellator::new(); let initial_indices_count = buffer.indices.len(); @@ -124,11 +128,11 @@ impl< tesselator .tessellate_path( &tile_path, - &FillOptions::default(), - &mut BuffersBuilder::new(buffer, WithId(prim_id)), + &FillOptions::tolerance(DEFAULT_TOLERANCE), + &mut BuffersBuilder::new(buffer, VertexConstructor()), ) .unwrap(); - initial_indices_count as u32..buffer.indices.len() as u32 + initial_indices_count as IndexDataType..buffer.indices.len() as IndexDataType } }