Fix Mesh allocator bug and reduce Mesh data copies by two (#15566)
# Objective - First step towards #15558 ## Solution - Rename `get_vertex_buffer_data` to `create_packed_vertex_buffer_data` to make it clear that it is not "free" and actually allocates - Compute length analytically for preallocation instead of creating the buffer to get its length and immediately discard it - Use existing vertex attribute size calculation method to reduce code duplication - Fix a bug where mesh index data was being replaced by unnecessarily newly created mesh vertex data in some cases - Overall reduces mesh copies by two. We still have plenty to go, but these were the easy ones. ## Testing - I ran 3d_scene, lighting, and many_cubes, they look fine. - Benchmarks would be nice, but this is very obviously a win in perf and correctness. --- ## Migration Guide - `Mesh::create_packed_vertex_buffer_data` has been renamed `Mesh::create_packed_vertex_buffer_data` to reflect the fact that it copies data and allocates. ## Showcase - look mom, less copies
This commit is contained in:
parent
1df8238e8d
commit
6465e3bd9f
@ -30,7 +30,7 @@ impl MeshletMesh {
|
|||||||
let indices = validate_input_mesh(mesh)?;
|
let indices = validate_input_mesh(mesh)?;
|
||||||
|
|
||||||
// Split the mesh into an initial list of meshlets (LOD 0)
|
// Split the mesh into an initial list of meshlets (LOD 0)
|
||||||
let vertex_buffer = mesh.get_vertex_buffer_data();
|
let vertex_buffer = mesh.create_packed_vertex_buffer_data();
|
||||||
let vertex_stride = mesh.get_vertex_size() as usize;
|
let vertex_stride = mesh.get_vertex_size() as usize;
|
||||||
let vertices = VertexDataAdapter::new(&vertex_buffer, vertex_stride, 0).unwrap();
|
let vertices = VertexDataAdapter::new(&vertex_buffer, vertex_stride, 0).unwrap();
|
||||||
let mut meshlets = compute_meshlets(&indices, &vertices);
|
let mut meshlets = compute_meshlets(&indices, &vertices);
|
||||||
|
|||||||
@ -427,7 +427,7 @@ impl MeshAllocator {
|
|||||||
if self.general_vertex_slabs_supported {
|
if self.general_vertex_slabs_supported {
|
||||||
self.allocate(
|
self.allocate(
|
||||||
mesh_id,
|
mesh_id,
|
||||||
mesh.get_vertex_buffer_data().len() as u64,
|
mesh.get_vertex_size() * mesh.count_vertices() as u64,
|
||||||
vertex_element_layout,
|
vertex_element_layout,
|
||||||
&mut slabs_to_grow,
|
&mut slabs_to_grow,
|
||||||
mesh_allocator_settings,
|
mesh_allocator_settings,
|
||||||
@ -474,12 +474,11 @@ impl MeshAllocator {
|
|||||||
let Some(&slab_id) = self.mesh_id_to_vertex_slab.get(mesh_id) else {
|
let Some(&slab_id) = self.mesh_id_to_vertex_slab.get(mesh_id) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let vertex_data = mesh.get_vertex_buffer_data();
|
let vertex_data = mesh.create_packed_vertex_buffer_data();
|
||||||
|
|
||||||
// Call the generic function.
|
// Call the generic function.
|
||||||
self.copy_element_data(
|
self.copy_element_data(
|
||||||
mesh_id,
|
mesh_id,
|
||||||
mesh,
|
|
||||||
&vertex_data,
|
&vertex_data,
|
||||||
BufferUsages::VERTEX,
|
BufferUsages::VERTEX,
|
||||||
slab_id,
|
slab_id,
|
||||||
@ -507,7 +506,6 @@ impl MeshAllocator {
|
|||||||
// Call the generic function.
|
// Call the generic function.
|
||||||
self.copy_element_data(
|
self.copy_element_data(
|
||||||
mesh_id,
|
mesh_id,
|
||||||
mesh,
|
|
||||||
index_data,
|
index_data,
|
||||||
BufferUsages::INDEX,
|
BufferUsages::INDEX,
|
||||||
slab_id,
|
slab_id,
|
||||||
@ -521,7 +519,6 @@ impl MeshAllocator {
|
|||||||
fn copy_element_data(
|
fn copy_element_data(
|
||||||
&mut self,
|
&mut self,
|
||||||
mesh_id: &AssetId<Mesh>,
|
mesh_id: &AssetId<Mesh>,
|
||||||
mesh: &Mesh,
|
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
buffer_usages: BufferUsages,
|
buffer_usages: BufferUsages,
|
||||||
slab_id: SlabId,
|
slab_id: SlabId,
|
||||||
@ -567,7 +564,7 @@ impl MeshAllocator {
|
|||||||
slab_id,
|
slab_id,
|
||||||
buffer_usages_to_str(buffer_usages)
|
buffer_usages_to_str(buffer_usages)
|
||||||
)),
|
)),
|
||||||
contents: &mesh.get_vertex_buffer_data(),
|
contents: data,
|
||||||
usage: buffer_usages | BufferUsages::COPY_DST,
|
usage: buffer_usages | BufferUsages::COPY_DST,
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|||||||
@ -458,13 +458,8 @@ impl Mesh {
|
|||||||
///
|
///
|
||||||
/// If the vertex attributes have different lengths, they are all truncated to
|
/// If the vertex attributes have different lengths, they are all truncated to
|
||||||
/// the length of the smallest.
|
/// the length of the smallest.
|
||||||
pub fn get_vertex_buffer_data(&self) -> Vec<u8> {
|
pub fn create_packed_vertex_buffer_data(&self) -> Vec<u8> {
|
||||||
let mut vertex_size = 0;
|
let vertex_size = self.get_vertex_size() as usize;
|
||||||
for attribute_data in self.attributes.values() {
|
|
||||||
let vertex_format = attribute_data.attribute.format;
|
|
||||||
vertex_size += vertex_format.get_size() as usize;
|
|
||||||
}
|
|
||||||
|
|
||||||
let vertex_count = self.count_vertices();
|
let vertex_count = self.count_vertices();
|
||||||
let mut attributes_interleaved_buffer = vec![0; vertex_count * vertex_size];
|
let mut attributes_interleaved_buffer = vec![0; vertex_count * vertex_size];
|
||||||
// bundle into interleaved buffers
|
// bundle into interleaved buffers
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user