diff --git a/src/cache.rs b/src/cache.rs index f91ace8..1acd514 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -5,9 +5,9 @@ use wgpu::{ BindingResource, BindingType, BlendState, Buffer, BufferBindingType, ColorTargetState, ColorWrites, DepthStencilState, Device, FilterMode, FragmentState, MultisampleState, PipelineCompilationOptions, PipelineLayout, PipelineLayoutDescriptor, PrimitiveState, - RenderPipeline, RenderPipelineDescriptor, Sampler, SamplerBindingType, SamplerDescriptor, - ShaderModule, ShaderModuleDescriptor, ShaderSource, ShaderStages, TextureFormat, - TextureSampleType, TextureView, TextureViewDimension, VertexFormat, VertexState, + PrimitiveTopology, RenderPipeline, RenderPipelineDescriptor, Sampler, SamplerBindingType, + SamplerDescriptor, ShaderModule, ShaderModuleDescriptor, ShaderSource, ShaderStages, + TextureFormat, TextureSampleType, TextureView, TextureViewDimension, VertexFormat, VertexState, }; use std::borrow::Cow; @@ -56,7 +56,7 @@ impl Cache { let vertex_buffer_layout = wgpu::VertexBufferLayout { array_stride: mem::size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, + step_mode: wgpu::VertexStepMode::Instance, attributes: &[ wgpu::VertexAttribute { format: VertexFormat::Sint32x2, @@ -232,7 +232,10 @@ impl Cache { })], compilation_options: PipelineCompilationOptions::default(), }), - primitive: PrimitiveState::default(), + primitive: PrimitiveState { + topology: PrimitiveTopology::TriangleStrip, + ..Default::default() + }, depth_stencil: depth_stencil.clone(), multisample, multiview: None, diff --git a/src/shader.wgsl b/src/shader.wgsl index eae770a..1813a66 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -47,25 +47,17 @@ fn vs_main(in_vert: VertexInput) -> VertexOutput { let height = (in_vert.dim & 0xffff0000u) >> 16u; let color = in_vert.color; var uv = vec2(in_vert.uv & 0xffffu, (in_vert.uv & 0xffff0000u) >> 16u); - let v = in_vert.vertex_idx % 4u; + let v = in_vert.vertex_idx; - switch v { - case 1u: { - pos.x += i32(width); - uv.x += width; - } - case 2u: { - pos.x += i32(width); - pos.y += i32(height); - uv.x += width; - uv.y += height; - } - case 3u: { - pos.y += i32(height); - uv.y += height; - } - default: {} - } + let corner_position = vec2( + in_vert.vertex_idx & 1u, + (in_vert.vertex_idx >> 1u) & 1u, + ); + + let corner_offset = vec2(width, height) * corner_position; + + uv = uv + corner_offset; + pos = pos + vec2(corner_offset); var vert_output: VertexOutput; diff --git a/src/text_render.rs b/src/text_render.rs index 23ca20f..ce5549b 100644 --- a/src/text_render.rs +++ b/src/text_render.rs @@ -2,23 +2,19 @@ use crate::{ ColorMode, FontSystem, GlyphDetails, GlyphToRender, GpuCacheStatus, PrepareError, RenderError, SwashCache, SwashContent, TextArea, TextAtlas, Viewport, }; -use std::{iter, slice, sync::Arc}; +use std::{slice, sync::Arc}; use wgpu::{ Buffer, BufferDescriptor, BufferUsages, DepthStencilState, Device, Extent3d, ImageCopyTexture, - ImageDataLayout, IndexFormat, MultisampleState, Origin3d, Queue, RenderPass, RenderPipeline, - TextureAspect, COPY_BUFFER_ALIGNMENT, + ImageDataLayout, MultisampleState, Origin3d, Queue, RenderPass, RenderPipeline, TextureAspect, + COPY_BUFFER_ALIGNMENT, }; /// A text renderer that uses cached glyphs to render text into an existing render pass. pub struct TextRenderer { vertex_buffer: Buffer, vertex_buffer_size: u64, - index_buffer: Buffer, - index_buffer_size: u64, - vertices_to_render: u32, pipeline: Arc, glyph_vertices: Vec, - glyph_indices: Vec, } impl TextRenderer { @@ -37,25 +33,13 @@ impl TextRenderer { mapped_at_creation: false, }); - let index_buffer_size = next_copy_buffer_size(4096); - let index_buffer = device.create_buffer(&BufferDescriptor { - label: Some("glyphon indices"), - size: index_buffer_size, - usage: BufferUsages::INDEX | BufferUsages::COPY_DST, - mapped_at_creation: false, - }); - let pipeline = atlas.get_or_create_pipeline(device, multisample, depth_stencil); Self { vertex_buffer, vertex_buffer_size, - index_buffer, - index_buffer_size, - vertices_to_render: 0, pipeline, glyph_vertices: Vec::new(), - glyph_indices: Vec::new(), } } @@ -72,8 +56,6 @@ impl TextRenderer { mut metadata_to_depth: impl FnMut(usize) -> f32, ) -> Result<(), PrepareError> { self.glyph_vertices.clear(); - self.glyph_indices.clear(); - let mut glyphs_added = 0; let resolution = viewport.resolution(); @@ -257,43 +239,25 @@ impl TextRenderer { let depth = metadata_to_depth(glyph.metadata); - self.glyph_vertices.extend( - iter::repeat(GlyphToRender { - pos: [x, y], - dim: [width as u16, height as u16], - uv: [atlas_x, atlas_y], - color: color.0, - content_type_with_srgb: [ - content_type as u16, - match atlas.color_mode { - ColorMode::Accurate => TextColorConversion::ConvertToLinear, - ColorMode::Web => TextColorConversion::None, - } as u16, - ], - depth, - }) - .take(4), - ); - - let start = 4 * glyphs_added as u32; - self.glyph_indices.extend([ - start, - start + 1, - start + 2, - start, - start + 2, - start + 3, - ]); - - glyphs_added += 1; + self.glyph_vertices.push(GlyphToRender { + pos: [x, y], + dim: [width as u16, height as u16], + uv: [atlas_x, atlas_y], + color: color.0, + content_type_with_srgb: [ + content_type as u16, + match atlas.color_mode { + ColorMode::Accurate => TextColorConversion::ConvertToLinear, + ColorMode::Web => TextColorConversion::None, + } as u16, + ], + depth, + }); } } } - const VERTICES_PER_GLYPH: u32 = 6; - self.vertices_to_render = glyphs_added as u32 * VERTICES_PER_GLYPH; - - let will_render = glyphs_added > 0; + let will_render = !self.glyph_vertices.is_empty(); if !will_render { return Ok(()); } @@ -322,30 +286,6 @@ impl TextRenderer { self.vertex_buffer_size = buffer_size; } - let indices = self.glyph_indices.as_slice(); - let indices_raw = unsafe { - slice::from_raw_parts( - indices as *const _ as *const u8, - std::mem::size_of_val(indices), - ) - }; - - if self.index_buffer_size >= indices_raw.len() as u64 { - queue.write_buffer(&self.index_buffer, 0, indices_raw); - } else { - self.index_buffer.destroy(); - - let (buffer, buffer_size) = create_oversized_buffer( - device, - Some("glyphon indices"), - indices_raw, - BufferUsages::INDEX | BufferUsages::COPY_DST, - ); - - self.index_buffer = buffer; - self.index_buffer_size = buffer_size; - } - Ok(()) } @@ -378,7 +318,7 @@ impl TextRenderer { viewport: &'pass Viewport, pass: &mut RenderPass<'pass>, ) -> Result<(), RenderError> { - if self.vertices_to_render == 0 { + if self.glyph_vertices.is_empty() { return Ok(()); } @@ -386,8 +326,7 @@ impl TextRenderer { pass.set_bind_group(0, &atlas.bind_group, &[]); pass.set_bind_group(1, &viewport.bind_group, &[]); pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); - pass.set_index_buffer(self.index_buffer.slice(..), IndexFormat::Uint32); - pass.draw_indexed(0..self.vertices_to_render, 0, 0..1); + pass.draw(0..4, 0..self.glyph_vertices.len() as u32); Ok(()) }