Fix memory leak in iced_wgpu::Buffer
I know, I know... Skill issue.
This commit is contained in:
parent
26dfcb6d42
commit
92888a3639
2 changed files with 30 additions and 39 deletions
|
|
@ -13,7 +13,6 @@ pub struct Buffer<T> {
|
||||||
size: u64,
|
size: u64,
|
||||||
usage: wgpu::BufferUsages,
|
usage: wgpu::BufferUsages,
|
||||||
pub(crate) raw: wgpu::Buffer,
|
pub(crate) raw: wgpu::Buffer,
|
||||||
offsets: Vec<wgpu::BufferAddress>,
|
|
||||||
type_: PhantomData<T>,
|
type_: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,7 +37,6 @@ impl<T: bytemuck::Pod> Buffer<T> {
|
||||||
size,
|
size,
|
||||||
usage,
|
usage,
|
||||||
raw,
|
raw,
|
||||||
offsets: Vec::new(),
|
|
||||||
type_: PhantomData,
|
type_: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -47,8 +45,6 @@ impl<T: bytemuck::Pod> Buffer<T> {
|
||||||
let new_size = (std::mem::size_of::<T>() * new_count) as u64;
|
let new_size = (std::mem::size_of::<T>() * new_count) as u64;
|
||||||
|
|
||||||
if self.size < new_size {
|
if self.size < new_size {
|
||||||
self.offsets.clear();
|
|
||||||
|
|
||||||
self.raw = device.create_buffer(&wgpu::BufferDescriptor {
|
self.raw = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
label: Some(self.label),
|
label: Some(self.label),
|
||||||
size: new_size,
|
size: new_size,
|
||||||
|
|
@ -108,8 +104,6 @@ impl<T: bytemuck::Pod> Buffer<T> {
|
||||||
)
|
)
|
||||||
.copy_from_slice(&bytes[bytes_written..]);
|
.copy_from_slice(&bytes[bytes_written..]);
|
||||||
|
|
||||||
self.offsets.push(offset as u64);
|
|
||||||
|
|
||||||
bytes.len()
|
bytes.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,19 +114,11 @@ impl<T: bytemuck::Pod> Buffer<T> {
|
||||||
self.raw.slice(bounds)
|
self.raw.slice(bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the slice calculated from the offset stored at the given index.
|
pub fn range(&self, start: usize, end: usize) -> wgpu::BufferSlice<'_> {
|
||||||
pub fn slice_from_index(&self, index: usize) -> wgpu::BufferSlice<'_> {
|
self.slice(
|
||||||
self.raw.slice(self.offset_at(index)..)
|
start as u64 * std::mem::size_of::<T>() as u64
|
||||||
}
|
..end as u64 * std::mem::size_of::<T>() as u64,
|
||||||
|
)
|
||||||
/// Clears any temporary data (i.e. offsets) from the buffer.
|
|
||||||
pub fn clear(&mut self) {
|
|
||||||
self.offsets.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the offset at `index`, if it exists.
|
|
||||||
fn offset_at(&self, index: usize) -> &wgpu::BufferAddress {
|
|
||||||
self.offsets.get(index).expect("No offset at index.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -368,7 +368,6 @@ fn render<'a>(
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Layer {
|
pub struct Layer {
|
||||||
index_buffer: Buffer<u32>,
|
index_buffer: Buffer<u32>,
|
||||||
index_strides: Vec<u32>,
|
|
||||||
solid: solid::Layer,
|
solid: solid::Layer,
|
||||||
gradient: gradient::Layer,
|
gradient: gradient::Layer,
|
||||||
}
|
}
|
||||||
|
|
@ -386,7 +385,6 @@ impl Layer {
|
||||||
INITIAL_INDEX_COUNT,
|
INITIAL_INDEX_COUNT,
|
||||||
wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
|
wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
|
||||||
),
|
),
|
||||||
index_strides: Vec::new(),
|
|
||||||
solid: solid::Layer::new(device, &solid.constants_layout),
|
solid: solid::Layer::new(device, &solid.constants_layout),
|
||||||
gradient: gradient::Layer::new(device, &gradient.constants_layout),
|
gradient: gradient::Layer::new(device, &gradient.constants_layout),
|
||||||
}
|
}
|
||||||
|
|
@ -432,13 +430,6 @@ impl Layer {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.index_strides.clear();
|
|
||||||
self.index_buffer.clear();
|
|
||||||
self.solid.vertices.clear();
|
|
||||||
self.solid.uniforms.clear();
|
|
||||||
self.gradient.vertices.clear();
|
|
||||||
self.gradient.uniforms.clear();
|
|
||||||
|
|
||||||
let mut solid_vertex_offset = 0;
|
let mut solid_vertex_offset = 0;
|
||||||
let mut solid_uniform_offset = 0;
|
let mut solid_uniform_offset = 0;
|
||||||
let mut gradient_vertex_offset = 0;
|
let mut gradient_vertex_offset = 0;
|
||||||
|
|
@ -474,8 +465,6 @@ impl Layer {
|
||||||
indices,
|
indices,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.index_strides.push(indices.len() as u32);
|
|
||||||
|
|
||||||
match mesh {
|
match mesh {
|
||||||
Mesh::Solid { buffers, .. } => {
|
Mesh::Solid { buffers, .. } => {
|
||||||
solid_vertex_offset += self.solid.vertices.write(
|
solid_vertex_offset += self.solid.vertices.write(
|
||||||
|
|
@ -526,18 +515,23 @@ impl Layer {
|
||||||
) {
|
) {
|
||||||
let mut num_solids = 0;
|
let mut num_solids = 0;
|
||||||
let mut num_gradients = 0;
|
let mut num_gradients = 0;
|
||||||
|
let mut solid_offset = 0;
|
||||||
|
let mut gradient_offset = 0;
|
||||||
|
let mut index_offset = 0;
|
||||||
let mut last_is_solid = None;
|
let mut last_is_solid = None;
|
||||||
|
|
||||||
for (index, mesh) in meshes.iter().enumerate() {
|
for mesh in meshes {
|
||||||
let Some(clip_bounds) = bounds
|
let Some(clip_bounds) = bounds
|
||||||
.intersection(&(mesh.clip_bounds() * transformation))
|
.intersection(&(mesh.clip_bounds() * transformation))
|
||||||
.and_then(Rectangle::snap)
|
.and_then(Rectangle::snap)
|
||||||
else {
|
else {
|
||||||
match mesh {
|
match mesh {
|
||||||
Mesh::Solid { .. } => {
|
Mesh::Solid { buffers, .. } => {
|
||||||
|
solid_offset += buffers.vertices.len();
|
||||||
num_solids += 1;
|
num_solids += 1;
|
||||||
}
|
}
|
||||||
Mesh::Gradient { .. } => {
|
Mesh::Gradient { buffers, .. } => {
|
||||||
|
gradient_offset += buffers.vertices.len();
|
||||||
num_gradients += 1;
|
num_gradients += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -552,7 +546,7 @@ impl Layer {
|
||||||
);
|
);
|
||||||
|
|
||||||
match mesh {
|
match mesh {
|
||||||
Mesh::Solid { .. } => {
|
Mesh::Solid { buffers, .. } => {
|
||||||
if !last_is_solid.unwrap_or(false) {
|
if !last_is_solid.unwrap_or(false) {
|
||||||
render_pass.set_pipeline(&solid.pipeline);
|
render_pass.set_pipeline(&solid.pipeline);
|
||||||
|
|
||||||
|
|
@ -568,12 +562,16 @@ impl Layer {
|
||||||
|
|
||||||
render_pass.set_vertex_buffer(
|
render_pass.set_vertex_buffer(
|
||||||
0,
|
0,
|
||||||
self.solid.vertices.slice_from_index(num_solids),
|
self.solid.vertices.range(
|
||||||
|
solid_offset,
|
||||||
|
solid_offset + buffers.vertices.len(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
num_solids += 1;
|
num_solids += 1;
|
||||||
|
solid_offset += buffers.vertices.len();
|
||||||
}
|
}
|
||||||
Mesh::Gradient { .. } => {
|
Mesh::Gradient { buffers, .. } => {
|
||||||
if last_is_solid.unwrap_or(true) {
|
if last_is_solid.unwrap_or(true) {
|
||||||
render_pass.set_pipeline(&gradient.pipeline);
|
render_pass.set_pipeline(&gradient.pipeline);
|
||||||
|
|
||||||
|
|
@ -589,19 +587,26 @@ impl Layer {
|
||||||
|
|
||||||
render_pass.set_vertex_buffer(
|
render_pass.set_vertex_buffer(
|
||||||
0,
|
0,
|
||||||
self.gradient.vertices.slice_from_index(num_gradients),
|
self.solid.vertices.range(
|
||||||
|
gradient_offset,
|
||||||
|
gradient_offset + buffers.vertices.len(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
num_gradients += 1;
|
num_gradients += 1;
|
||||||
|
gradient_offset += buffers.vertices.len();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
render_pass.set_index_buffer(
|
render_pass.set_index_buffer(
|
||||||
self.index_buffer.slice_from_index(index),
|
self.index_buffer
|
||||||
|
.range(index_offset, index_offset + mesh.indices().len()),
|
||||||
wgpu::IndexFormat::Uint32,
|
wgpu::IndexFormat::Uint32,
|
||||||
);
|
);
|
||||||
|
|
||||||
render_pass.draw_indexed(0..self.index_strides[index], 0, 0..1);
|
render_pass.draw_indexed(0..mesh.indices().len() as u32, 0, 0..1);
|
||||||
|
|
||||||
|
index_offset += mesh.indices().len();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue