Path: blob/main/crates/bevy_pbr/src/meshlet/meshlet_mesh_manager.rs
6600 views
use crate::meshlet::asset::{BvhNode, MeshletAabb, MeshletCullData};12use super::{asset::Meshlet, persistent_buffer::PersistentGpuBuffer, MeshletMesh};3use alloc::sync::Arc;4use bevy_asset::{AssetId, Assets};5use bevy_ecs::{6resource::Resource,7system::{Commands, Res, ResMut},8};9use bevy_math::Vec2;10use bevy_platform::collections::HashMap;11use bevy_render::{12render_resource::BufferAddress,13renderer::{RenderDevice, RenderQueue},14};15use core::ops::Range;1617/// Manages uploading [`MeshletMesh`] asset data to the GPU.18#[derive(Resource)]19pub struct MeshletMeshManager {20pub vertex_positions: PersistentGpuBuffer<Arc<[u32]>>,21pub vertex_normals: PersistentGpuBuffer<Arc<[u32]>>,22pub vertex_uvs: PersistentGpuBuffer<Arc<[Vec2]>>,23pub indices: PersistentGpuBuffer<Arc<[u8]>>,24pub bvh_nodes: PersistentGpuBuffer<Arc<[BvhNode]>>,25pub meshlets: PersistentGpuBuffer<Arc<[Meshlet]>>,26pub meshlet_cull_data: PersistentGpuBuffer<Arc<[MeshletCullData]>>,27meshlet_mesh_slices:28HashMap<AssetId<MeshletMesh>, ([Range<BufferAddress>; 7], MeshletAabb, u32)>,29}3031pub fn init_meshlet_mesh_manager(mut commands: Commands, render_device: Res<RenderDevice>) {32commands.insert_resource(MeshletMeshManager {33vertex_positions: PersistentGpuBuffer::new("meshlet_vertex_positions", &render_device),34vertex_normals: PersistentGpuBuffer::new("meshlet_vertex_normals", &render_device),35vertex_uvs: PersistentGpuBuffer::new("meshlet_vertex_uvs", &render_device),36indices: PersistentGpuBuffer::new("meshlet_indices", &render_device),37bvh_nodes: PersistentGpuBuffer::new("meshlet_bvh_nodes", &render_device),38meshlets: PersistentGpuBuffer::new("meshlets", &render_device),39meshlet_cull_data: PersistentGpuBuffer::new("meshlet_cull_data", &render_device),40meshlet_mesh_slices: HashMap::default(),41});42}4344impl MeshletMeshManager {45// Returns the index of the root BVH node, as well as the depth of the BVH.46pub fn queue_upload_if_needed(47&mut self,48asset_id: AssetId<MeshletMesh>,49assets: &mut Assets<MeshletMesh>,50) -> (u32, MeshletAabb, u32) {51let queue_meshlet_mesh = |asset_id: &AssetId<MeshletMesh>| {52let meshlet_mesh = assets.remove_untracked(*asset_id).expect(53"MeshletMesh asset was already unloaded but is not registered with MeshletMeshManager",54);5556let vertex_positions_slice = self57.vertex_positions58.queue_write(Arc::clone(&meshlet_mesh.vertex_positions), ());59let vertex_normals_slice = self60.vertex_normals61.queue_write(Arc::clone(&meshlet_mesh.vertex_normals), ());62let vertex_uvs_slice = self63.vertex_uvs64.queue_write(Arc::clone(&meshlet_mesh.vertex_uvs), ());65let indices_slice = self66.indices67.queue_write(Arc::clone(&meshlet_mesh.indices), ());68let meshlets_slice = self.meshlets.queue_write(69Arc::clone(&meshlet_mesh.meshlets),70(71vertex_positions_slice.start,72vertex_normals_slice.start,73indices_slice.start,74),75);76let base_meshlet_index = (meshlets_slice.start / size_of::<Meshlet>() as u64) as u32;77let bvh_node_slice = self78.bvh_nodes79.queue_write(Arc::clone(&meshlet_mesh.bvh), base_meshlet_index);80let meshlet_cull_data_slice = self81.meshlet_cull_data82.queue_write(Arc::clone(&meshlet_mesh.meshlet_cull_data), ());8384(85[86vertex_positions_slice,87vertex_normals_slice,88vertex_uvs_slice,89indices_slice,90bvh_node_slice,91meshlets_slice,92meshlet_cull_data_slice,93],94meshlet_mesh.aabb,95meshlet_mesh.bvh_depth,96)97};9899// If the MeshletMesh asset has not been uploaded to the GPU yet, queue it for uploading100let ([_, _, _, _, bvh_node_slice, _, _], aabb, bvh_depth) = self101.meshlet_mesh_slices102.entry(asset_id)103.or_insert_with_key(queue_meshlet_mesh)104.clone();105106(107(bvh_node_slice.start / size_of::<BvhNode>() as u64) as u32,108aabb,109bvh_depth,110)111}112113pub fn remove(&mut self, asset_id: &AssetId<MeshletMesh>) {114if let Some((115[vertex_positions_slice, vertex_normals_slice, vertex_uvs_slice, indices_slice, bvh_node_slice, meshlets_slice, meshlet_cull_data_slice],116_,117_,118)) = self.meshlet_mesh_slices.remove(asset_id)119{120self.vertex_positions121.mark_slice_unused(vertex_positions_slice);122self.vertex_normals.mark_slice_unused(vertex_normals_slice);123self.vertex_uvs.mark_slice_unused(vertex_uvs_slice);124self.indices.mark_slice_unused(indices_slice);125self.bvh_nodes.mark_slice_unused(bvh_node_slice);126self.meshlets.mark_slice_unused(meshlets_slice);127self.meshlet_cull_data128.mark_slice_unused(meshlet_cull_data_slice);129}130}131}132133/// Upload all newly queued [`MeshletMesh`] asset data to the GPU.134pub fn perform_pending_meshlet_mesh_writes(135mut meshlet_mesh_manager: ResMut<MeshletMeshManager>,136render_queue: Res<RenderQueue>,137render_device: Res<RenderDevice>,138) {139meshlet_mesh_manager140.vertex_positions141.perform_writes(&render_queue, &render_device);142meshlet_mesh_manager143.vertex_normals144.perform_writes(&render_queue, &render_device);145meshlet_mesh_manager146.vertex_uvs147.perform_writes(&render_queue, &render_device);148meshlet_mesh_manager149.indices150.perform_writes(&render_queue, &render_device);151meshlet_mesh_manager152.bvh_nodes153.perform_writes(&render_queue, &render_device);154meshlet_mesh_manager155.meshlets156.perform_writes(&render_queue, &render_device);157meshlet_mesh_manager158.meshlet_cull_data159.perform_writes(&render_queue, &render_device);160}161162163