Use oversized buffers

This commit is contained in:
grovesNL 2022-05-10 08:48:28 -02:30
parent 8bf8533ead
commit 781bed2c42
2 changed files with 52 additions and 19 deletions

View file

@ -71,7 +71,6 @@ async fn run() {
let font = include_bytes!("./Inter-Bold.ttf") as &[u8]; let font = include_bytes!("./Inter-Bold.ttf") as &[u8];
let font = Font::from_bytes(font, FontSettings::default()).unwrap(); let font = Font::from_bytes(font, FontSettings::default()).unwrap();
let fonts = vec![font]; let fonts = vec![font];
let mut layout = Layout::new(CoordinateSystem::PositiveYDown);
event_loop.run(move |event, _, control_flow| { event_loop.run(move |event, _, control_flow| {
let _ = (&instance, &adapter); let _ = (&instance, &adapter);
@ -88,6 +87,8 @@ async fn run() {
window.request_redraw(); window.request_redraw();
} }
Event::RedrawRequested(_) => { Event::RedrawRequested(_) => {
let mut layout = Layout::new(CoordinateSystem::PositiveYDown);
layout.reset(&LayoutSettings { layout.reset(&LayoutSettings {
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
@ -113,7 +114,7 @@ async fn run() {
height: config.height, height: config.height,
}, },
&fonts, &fonts,
&[&layout], &[layout],
) )
.unwrap(); .unwrap();

View file

@ -15,7 +15,6 @@ use fontdue::{
Font, Font,
}; };
use wgpu::{ use wgpu::{
util::{BufferInitDescriptor, DeviceExt},
BindGroup, BindGroupEntry, BindGroupLayoutEntry, BindingResource, BindingType, BlendState, BindGroup, BindGroupEntry, BindGroupLayoutEntry, BindingResource, BindingType, BlendState,
Buffer, BufferBindingType, BufferDescriptor, BufferUsages, ColorTargetState, ColorWrites, Buffer, BufferBindingType, BufferDescriptor, BufferUsages, ColorTargetState, ColorWrites,
Device, Extent3d, FilterMode, FragmentState, ImageCopyTexture, ImageDataLayout, IndexFormat, Device, Extent3d, FilterMode, FragmentState, ImageCopyTexture, ImageDataLayout, IndexFormat,
@ -23,7 +22,7 @@ use wgpu::{
RenderPipeline, RenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor, RenderPipeline, RenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor,
ShaderModuleDescriptor, ShaderSource, ShaderStages, Texture, TextureAspect, TextureDescriptor, ShaderModuleDescriptor, ShaderSource, ShaderStages, Texture, TextureAspect, TextureDescriptor,
TextureDimension, TextureFormat, TextureSampleType, TextureUsages, TextureViewDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages, TextureViewDescriptor,
TextureViewDimension, VertexFormat, VertexState, TextureViewDimension, VertexFormat, VertexState, COPY_BUFFER_ALIGNMENT,
}; };
pub use fontdue; pub use fontdue;
@ -317,7 +316,7 @@ impl TextRenderer {
multiview: None, multiview: None,
}); });
let vertex_buffer_size = 4096; let vertex_buffer_size = next_copy_buffer_size(4096);
let vertex_buffer = device.create_buffer(&BufferDescriptor { let vertex_buffer = device.create_buffer(&BufferDescriptor {
label: Some("glyphon vertices"), label: Some("glyphon vertices"),
size: vertex_buffer_size, size: vertex_buffer_size,
@ -325,7 +324,7 @@ impl TextRenderer {
mapped_at_creation: false, mapped_at_creation: false,
}); });
let index_buffer_size = 4096; let index_buffer_size = next_copy_buffer_size(4096);
let index_buffer = device.create_buffer(&BufferDescriptor { let index_buffer = device.create_buffer(&BufferDescriptor {
label: Some("glyphon indices"), label: Some("glyphon indices"),
size: index_buffer_size, size: index_buffer_size,
@ -358,7 +357,7 @@ impl TextRenderer {
queue: &Queue, queue: &Queue,
screen_resolution: Resolution, screen_resolution: Resolution,
fonts: &[Font], fonts: &[Font],
layouts: &[&Layout<impl HasColor>], layouts: &[Layout<impl HasColor>],
) -> Result<(), PrepareError> { ) -> Result<(), PrepareError> {
if screen_resolution != self.params.screen_resolution { if screen_resolution != self.params.screen_resolution {
self.params.screen_resolution = screen_resolution; self.params.screen_resolution = screen_resolution;
@ -531,12 +530,16 @@ impl TextRenderer {
queue.write_buffer(&self.vertex_buffer, 0, vertices_raw); queue.write_buffer(&self.vertex_buffer, 0, vertices_raw);
} else { } else {
self.vertex_buffer.destroy(); self.vertex_buffer.destroy();
self.vertex_buffer_size = vertices_raw.len().next_power_of_two() as u64;
self.vertex_buffer = device.create_buffer_init(&BufferInitDescriptor { let (buffer, buffer_size) = create_oversized_buffer(
label: Some("glyphon vertices"), device,
contents: vertices_raw, Some("glyphon vertices"),
usage: BufferUsages::VERTEX | BufferUsages::COPY_DST, vertices_raw,
}); BufferUsages::VERTEX | BufferUsages::COPY_DST,
);
self.vertex_buffer = buffer;
self.vertex_buffer_size = buffer_size;
} }
let indices = glyph_indices.as_slice(); let indices = glyph_indices.as_slice();
@ -551,12 +554,16 @@ impl TextRenderer {
queue.write_buffer(&self.index_buffer, 0, indices_raw); queue.write_buffer(&self.index_buffer, 0, indices_raw);
} else { } else {
self.index_buffer.destroy(); self.index_buffer.destroy();
self.index_buffer_size = indices_raw.len().next_power_of_two() as u64;
self.index_buffer = device.create_buffer_init(&BufferInitDescriptor { let (buffer, buffer_size) = create_oversized_buffer(
label: Some("glyphon indices"), device,
contents: indices_raw, Some("glyphon indices"),
usage: BufferUsages::INDEX | BufferUsages::COPY_DST, indices_raw,
}); BufferUsages::INDEX | BufferUsages::COPY_DST,
);
self.index_buffer = buffer;
self.index_buffer_size = buffer_size;
} }
Ok(()) Ok(())
@ -576,3 +583,28 @@ impl TextRenderer {
Ok(()) Ok(())
} }
} }
fn next_copy_buffer_size(size: u64) -> u64 {
let next_power_of_2 = size.next_power_of_two() as u64;
let align_mask = COPY_BUFFER_ALIGNMENT - 1;
let padded_size = ((next_power_of_2 + align_mask) & !align_mask).max(COPY_BUFFER_ALIGNMENT);
padded_size
}
fn create_oversized_buffer(
device: &Device,
label: Option<&str>,
contents: &[u8],
usage: BufferUsages,
) -> (Buffer, u64) {
let size = next_copy_buffer_size(contents.len() as u64);
let buffer = device.create_buffer(&BufferDescriptor {
label,
size,
usage,
mapped_at_creation: true,
});
buffer.slice(..).get_mapped_range_mut()[..contents.len()].copy_from_slice(contents);
buffer.unmap();
(buffer, size)
}