Avoid creating a vertex buffer every frame
This commit is contained in:
parent
59d45a5440
commit
c58d94f3fd
@ -22,6 +22,7 @@ pub struct Pipeline {
|
||||
uniforms: wgpu::Buffer,
|
||||
vertices: wgpu::Buffer,
|
||||
indices: wgpu::Buffer,
|
||||
instances: wgpu::Buffer,
|
||||
constants: wgpu::BindGroup,
|
||||
texture: wgpu::BindGroup,
|
||||
texture_version: usize,
|
||||
@ -188,7 +189,7 @@ impl Pipeline {
|
||||
},
|
||||
wgpu::VertexAttributeDescriptor {
|
||||
shader_location: 5,
|
||||
format: wgpu::VertexFormat::Float,
|
||||
format: wgpu::VertexFormat::Uint,
|
||||
offset: 4 * 8,
|
||||
},
|
||||
],
|
||||
@ -207,6 +208,11 @@ impl Pipeline {
|
||||
.create_buffer_mapped(QUAD_INDICES.len(), wgpu::BufferUsage::INDEX)
|
||||
.fill_from_slice(&QUAD_INDICES);
|
||||
|
||||
let instances = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size: mem::size_of::<Instance>() as u64 * Instance::MAX as u64,
|
||||
usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
|
||||
});
|
||||
|
||||
let texture_atlas = texture::Atlas::new(device);
|
||||
|
||||
let texture = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
@ -230,6 +236,7 @@ impl Pipeline {
|
||||
uniforms: uniforms_buffer,
|
||||
vertices,
|
||||
indices,
|
||||
instances,
|
||||
constants: constant_bind_group,
|
||||
texture,
|
||||
texture_version: texture_atlas.layer_count(),
|
||||
@ -341,49 +348,67 @@ impl Pipeline {
|
||||
);
|
||||
|
||||
let instances_buffer = device
|
||||
.create_buffer_mapped(instances.len(), wgpu::BufferUsage::VERTEX)
|
||||
.create_buffer_mapped(instances.len(), wgpu::BufferUsage::COPY_SRC)
|
||||
.fill_from_slice(&instances);
|
||||
|
||||
let mut render_pass =
|
||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[
|
||||
wgpu::RenderPassColorAttachmentDescriptor {
|
||||
attachment: target,
|
||||
resolve_target: None,
|
||||
load_op: wgpu::LoadOp::Load,
|
||||
store_op: wgpu::StoreOp::Store,
|
||||
clear_color: wgpu::Color {
|
||||
r: 0.0,
|
||||
g: 0.0,
|
||||
b: 0.0,
|
||||
a: 0.0,
|
||||
let mut i = 0;
|
||||
let total = instances.len();
|
||||
|
||||
while i < total {
|
||||
let end = (i + Instance::MAX).min(total);
|
||||
let amount = end - i;
|
||||
|
||||
encoder.copy_buffer_to_buffer(
|
||||
&instances_buffer,
|
||||
(i * std::mem::size_of::<Instance>()) as u64,
|
||||
&self.instances,
|
||||
0,
|
||||
(amount * std::mem::size_of::<Instance>()) as u64,
|
||||
);
|
||||
|
||||
let mut render_pass =
|
||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[
|
||||
wgpu::RenderPassColorAttachmentDescriptor {
|
||||
attachment: target,
|
||||
resolve_target: None,
|
||||
load_op: wgpu::LoadOp::Load,
|
||||
store_op: wgpu::StoreOp::Store,
|
||||
clear_color: wgpu::Color {
|
||||
r: 0.0,
|
||||
g: 0.0,
|
||||
b: 0.0,
|
||||
a: 0.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
|
||||
render_pass.set_pipeline(&self.pipeline);
|
||||
render_pass.set_bind_group(0, &self.constants, &[]);
|
||||
render_pass.set_bind_group(1, &self.texture, &[]);
|
||||
render_pass.set_index_buffer(&self.indices, 0);
|
||||
render_pass.set_vertex_buffers(
|
||||
0,
|
||||
&[(&self.vertices, 0), (&instances_buffer, 0)],
|
||||
);
|
||||
render_pass.set_pipeline(&self.pipeline);
|
||||
render_pass.set_bind_group(0, &self.constants, &[]);
|
||||
render_pass.set_bind_group(1, &self.texture, &[]);
|
||||
render_pass.set_index_buffer(&self.indices, 0);
|
||||
render_pass.set_vertex_buffers(
|
||||
0,
|
||||
&[(&self.vertices, 0), (&self.instances, 0)],
|
||||
);
|
||||
|
||||
render_pass.set_scissor_rect(
|
||||
bounds.x,
|
||||
bounds.y,
|
||||
bounds.width,
|
||||
bounds.height,
|
||||
);
|
||||
render_pass.set_scissor_rect(
|
||||
bounds.x,
|
||||
bounds.y,
|
||||
bounds.width,
|
||||
bounds.height,
|
||||
);
|
||||
|
||||
render_pass.draw_indexed(
|
||||
0..QUAD_INDICES.len() as u32,
|
||||
0,
|
||||
0..instances.len() as u32,
|
||||
);
|
||||
render_pass.draw_indexed(
|
||||
0..QUAD_INDICES.len() as u32,
|
||||
0,
|
||||
0..amount as u32,
|
||||
);
|
||||
|
||||
i += Instance::MAX;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trim_cache(&mut self) {
|
||||
@ -439,6 +464,10 @@ struct Instance {
|
||||
_layer: u32,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
pub const MAX: usize = 1_000;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct Uniforms {
|
||||
|
@ -86,8 +86,6 @@ impl Cache {
|
||||
let allocation =
|
||||
atlas.upload(width, height, &image, device, encoder)?;
|
||||
|
||||
dbg!("Uploaded");
|
||||
|
||||
*memory = Memory::Device(allocation);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ layout(location = 1) in vec2 i_Pos;
|
||||
layout(location = 2) in vec2 i_Scale;
|
||||
layout(location = 3) in vec2 i_Atlas_Pos;
|
||||
layout(location = 4) in vec2 i_Atlas_Scale;
|
||||
layout(location = 5) in float i_Layer;
|
||||
layout(location = 5) in uint i_Layer;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Globals {
|
||||
mat4 u_Transform;
|
||||
|
Binary file not shown.
@ -67,24 +67,22 @@ impl Atlas {
|
||||
where
|
||||
C: Copy + 'static,
|
||||
{
|
||||
let memory = {
|
||||
let entry = {
|
||||
let current_size = self.layers.len();
|
||||
let memory = self.allocate(width, height)?;
|
||||
let entry = self.allocate(width, height)?;
|
||||
|
||||
// We grow the internal texture after allocating if necessary
|
||||
let new_layers = self.layers.len() - current_size;
|
||||
self.grow(new_layers, device, encoder);
|
||||
|
||||
memory
|
||||
entry
|
||||
};
|
||||
|
||||
dbg!(&memory);
|
||||
|
||||
let buffer = device
|
||||
.create_buffer_mapped(data.len(), wgpu::BufferUsage::COPY_SRC)
|
||||
.fill_from_slice(data);
|
||||
|
||||
match &memory {
|
||||
match &entry {
|
||||
Entry::Contiguous(allocation) => {
|
||||
self.upload_texture(&buffer, 0, &allocation, encoder);
|
||||
}
|
||||
@ -105,7 +103,7 @@ impl Atlas {
|
||||
}
|
||||
}
|
||||
|
||||
Some(memory)
|
||||
Some(entry)
|
||||
}
|
||||
|
||||
fn allocate(&mut self, width: u32, height: u32) -> Option<Entry> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user