Skip to content

Commit 6465e3b

Browse files
authored
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
1 parent 1df8238 commit 6465e3b

File tree

3 files changed

+6
-14
lines changed

3 files changed

+6
-14
lines changed

crates/bevy_pbr/src/meshlet/from_mesh.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl MeshletMesh {
3030
let indices = validate_input_mesh(mesh)?;
3131

3232
// Split the mesh into an initial list of meshlets (LOD 0)
33-
let vertex_buffer = mesh.get_vertex_buffer_data();
33+
let vertex_buffer = mesh.create_packed_vertex_buffer_data();
3434
let vertex_stride = mesh.get_vertex_size() as usize;
3535
let vertices = VertexDataAdapter::new(&vertex_buffer, vertex_stride, 0).unwrap();
3636
let mut meshlets = compute_meshlets(&indices, &vertices);

crates/bevy_render/src/mesh/allocator.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ impl MeshAllocator {
427427
if self.general_vertex_slabs_supported {
428428
self.allocate(
429429
mesh_id,
430-
mesh.get_vertex_buffer_data().len() as u64,
430+
mesh.get_vertex_size() * mesh.count_vertices() as u64,
431431
vertex_element_layout,
432432
&mut slabs_to_grow,
433433
mesh_allocator_settings,
@@ -474,12 +474,11 @@ impl MeshAllocator {
474474
let Some(&slab_id) = self.mesh_id_to_vertex_slab.get(mesh_id) else {
475475
return;
476476
};
477-
let vertex_data = mesh.get_vertex_buffer_data();
477+
let vertex_data = mesh.create_packed_vertex_buffer_data();
478478

479479
// Call the generic function.
480480
self.copy_element_data(
481481
mesh_id,
482-
mesh,
483482
&vertex_data,
484483
BufferUsages::VERTEX,
485484
slab_id,
@@ -507,7 +506,6 @@ impl MeshAllocator {
507506
// Call the generic function.
508507
self.copy_element_data(
509508
mesh_id,
510-
mesh,
511509
index_data,
512510
BufferUsages::INDEX,
513511
slab_id,
@@ -521,7 +519,6 @@ impl MeshAllocator {
521519
fn copy_element_data(
522520
&mut self,
523521
mesh_id: &AssetId<Mesh>,
524-
mesh: &Mesh,
525522
data: &[u8],
526523
buffer_usages: BufferUsages,
527524
slab_id: SlabId,
@@ -567,7 +564,7 @@ impl MeshAllocator {
567564
slab_id,
568565
buffer_usages_to_str(buffer_usages)
569566
)),
570-
contents: &mesh.get_vertex_buffer_data(),
567+
contents: data,
571568
usage: buffer_usages | BufferUsages::COPY_DST,
572569
},
573570
));

crates/bevy_render/src/mesh/mesh/mod.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -458,13 +458,8 @@ impl Mesh {
458458
///
459459
/// If the vertex attributes have different lengths, they are all truncated to
460460
/// the length of the smallest.
461-
pub fn get_vertex_buffer_data(&self) -> Vec<u8> {
462-
let mut vertex_size = 0;
463-
for attribute_data in self.attributes.values() {
464-
let vertex_format = attribute_data.attribute.format;
465-
vertex_size += vertex_format.get_size() as usize;
466-
}
467-
461+
pub fn create_packed_vertex_buffer_data(&self) -> Vec<u8> {
462+
let vertex_size = self.get_vertex_size() as usize;
468463
let vertex_count = self.count_vertices();
469464
let mut attributes_interleaved_buffer = vec![0; vertex_count * vertex_size];
470465
// bundle into interleaved buffers

0 commit comments

Comments
 (0)