diff --git a/crates/bevy_pbr/src/nodes/lights_node.rs b/crates/bevy_pbr/src/nodes/lights_node.rs index 08ac9e926f..650fbb5d01 100644 --- a/crates/bevy_pbr/src/nodes/lights_node.rs +++ b/crates/bevy_pbr/src/nodes/lights_node.rs @@ -58,10 +58,8 @@ impl SystemNode for LightsNode { LightsNodeSystemState { command_queue: self.command_queue.clone(), max_lights: self.max_lights, - tmp_count_buffer: None, - tmp_light_buffer: None, light_buffer: None, - lights_are_dirty: true, + staging_buffer: None, }, ); system @@ -71,10 +69,7 @@ impl SystemNode for LightsNode { #[derive(Default)] pub struct LightsNodeSystemState { light_buffer: Option, - lights_are_dirty: bool, - // TODO: merge these - tmp_count_buffer: Option, - tmp_light_buffer: Option, + staging_buffer: Option, command_queue: CommandQueue, max_lights: usize, } @@ -82,22 +77,30 @@ pub struct LightsNodeSystemState { pub fn lights_node_system( mut state: Local, render_resource_context: Res>, - // TODO: this write on RenderResourceAssignments will prevent this system from running in parallel with other systems that do the same + // TODO: this write on RenderResourceBindings will prevent this system from running in parallel with other systems that do the same mut render_resource_bindings: ResMut, mut query: Query<(&Light, &Transform, &Translation)>, ) { let state = &mut state; - if !state.lights_are_dirty { - return; - } - let render_resource_context = &**render_resource_context; - if state.light_buffer.is_none() { - let light_uniform_size = - std::mem::size_of::() + state.max_lights * std::mem::size_of::(); + let light_count = query.iter().iter().count(); + let size = std::mem::size_of::(); + let light_count_size = std::mem::size_of::(); + let light_array_size = size * light_count; + let light_array_max_size = size * state.max_lights; + let current_light_uniform_size = light_count_size + light_array_size; + let max_light_uniform_size = light_count_size + light_array_max_size; + + if let Some(staging_buffer) = state.staging_buffer { + if light_count == 0 { + return; + } + + render_resource_context.map_buffer(staging_buffer); + } else { let buffer = render_resource_context.create_buffer(BufferInfo { - size: light_uniform_size, + size: max_light_uniform_size, buffer_usage: BufferUsage::UNIFORM | BufferUsage::COPY_SRC | BufferUsage::COPY_DST, ..Default::default() }); @@ -105,74 +108,45 @@ pub fn lights_node_system( uniform::LIGHTS, RenderResourceBinding::Buffer { buffer, - range: 0..light_uniform_size as u64, + range: 0..max_light_uniform_size as u64, dynamic_index: None, }, ); state.light_buffer = Some(buffer); + + let staging_buffer = render_resource_context.create_buffer(BufferInfo { + size: max_light_uniform_size, + buffer_usage: BufferUsage::COPY_SRC | BufferUsage::MAP_WRITE, + mapped_at_creation: true, + }); + state.staging_buffer = Some(staging_buffer); } - let light_count = query.iter().iter().count(); - - if light_count == 0 { - return; - } - - state.lights_are_dirty = false; - let size = std::mem::size_of::(); - let total_size = size * light_count; - let light_count_size = std::mem::size_of::(); - - if let Some(old_tmp_light_buffer) = state.tmp_light_buffer { - render_resource_context.remove_buffer(old_tmp_light_buffer); - } - - if let Some(old_tmp_count_buffer) = state.tmp_count_buffer { - render_resource_context.remove_buffer(old_tmp_count_buffer); - } - - state.tmp_light_buffer = Some(render_resource_context.create_buffer_mapped( - BufferInfo { - size: total_size, - buffer_usage: BufferUsage::COPY_SRC, - ..Default::default() - }, + let staging_buffer = state.staging_buffer.unwrap(); + render_resource_context.write_mapped_buffer( + staging_buffer, + 0..current_light_uniform_size as u64, &mut |data, _renderer| { + // light count + data[0..light_count_size].copy_from_slice([light_count as u32, 0, 0, 0].as_bytes()); + + // light array for ((light, transform, translation), slot) in - query.iter().iter().zip(data.chunks_exact_mut(size)) + query.iter().iter().zip(data[light_count_size..current_light_uniform_size].chunks_exact_mut(size)) { slot.copy_from_slice( LightRaw::from(&light, &transform.value, &translation).as_bytes(), ); } }, - )); - state.tmp_count_buffer = Some(render_resource_context.create_buffer_mapped( - BufferInfo { - size: light_count_size, - buffer_usage: BufferUsage::COPY_SRC, - ..Default::default() - }, - &mut |data, _renderer| { - data.copy_from_slice([light_count as u32, 0, 0, 0].as_bytes()); - }, - )); - let tmp_count_buffer = state.tmp_count_buffer.unwrap(); + ); + render_resource_context.unmap_buffer(staging_buffer); let light_buffer = state.light_buffer.unwrap(); state.command_queue.copy_buffer_to_buffer( - tmp_count_buffer, + staging_buffer, 0, light_buffer, 0, - light_count_size as u64, - ); - - let tmp_light_buffer = state.tmp_light_buffer.unwrap(); - state.command_queue.copy_buffer_to_buffer( - tmp_light_buffer, - 0, - light_buffer, - light_count_size as u64, - total_size as u64, + max_light_uniform_size as u64, ); } diff --git a/crates/bevy_render/src/render_graph/nodes/camera_node.rs b/crates/bevy_render/src/render_graph/nodes/camera_node.rs index 6ca49e2320..d4704279da 100644 --- a/crates/bevy_render/src/render_graph/nodes/camera_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/camera_node.rs @@ -51,6 +51,7 @@ impl SystemNode for CameraNode { camera_name: self.camera_name.clone(), command_queue: self.command_queue.clone(), camera_buffer: None, + staging_buffer: None, }, ); system @@ -62,6 +63,7 @@ pub struct CameraNodeState { command_queue: CommandQueue, camera_name: Cow<'static, str>, camera_buffer: Option, + staging_buffer: Option, } pub fn camera_node_system( @@ -74,27 +76,7 @@ pub fn camera_node_system( query: Query<(&Camera, &Transform)>, ) { let render_resource_context = &**render_resource_context; - state.camera_buffer = Some(match state.camera_buffer { - Some(buffer) => buffer, - None => { - let size = std::mem::size_of::<[[f32; 4]; 4]>(); - let buffer = render_resource_context.create_buffer(BufferInfo { - size, - buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, - ..Default::default() - }); - render_resource_bindings.set( - &state.camera_name, - RenderResourceBinding::Buffer { - buffer, - range: 0..size as u64, - dynamic_index: None, - }, - ); - state.camera_buffer = Some(buffer); - buffer - } - }); + let (camera, transform) = if let Some(camera_entity) = active_cameras.get(&state.camera_name) { ( query.get::(camera_entity).unwrap(), @@ -104,24 +86,55 @@ pub fn camera_node_system( return; }; + let staging_buffer = if let Some(staging_buffer) = state.staging_buffer { + render_resource_context.map_buffer(staging_buffer); + staging_buffer + } else { + let size = std::mem::size_of::<[[f32; 4]; 4]>(); + let buffer = render_resource_context.create_buffer(BufferInfo { + size, + buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, + ..Default::default() + }); + render_resource_bindings.set( + &state.camera_name, + RenderResourceBinding::Buffer { + buffer, + range: 0..size as u64, + dynamic_index: None, + }, + ); + state.camera_buffer = Some(buffer); + + let staging_buffer = render_resource_context.create_buffer(BufferInfo { + size, + buffer_usage: BufferUsage::COPY_SRC | BufferUsage::MAP_WRITE, + mapped_at_creation: true, + }); + + state.staging_buffer = Some(staging_buffer); + staging_buffer + }; + let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>(); let camera_matrix: [f32; 16] = (camera.projection_matrix * transform.value.inverse()).to_cols_array(); - let tmp_buffer = render_resource_context.create_buffer_mapped( - BufferInfo { - size: matrix_size, - buffer_usage: BufferUsage::COPY_SRC, - ..Default::default() - }, + render_resource_context.write_mapped_buffer( + staging_buffer, + 0..matrix_size as u64, &mut |data, _renderer| { data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes()); }, ); + render_resource_context.unmap_buffer(staging_buffer); let camera_buffer = state.camera_buffer.unwrap(); - state - .command_queue - .copy_buffer_to_buffer(tmp_buffer, 0, camera_buffer, 0, matrix_size as u64); - state.command_queue.free_buffer(tmp_buffer); + state.command_queue.copy_buffer_to_buffer( + staging_buffer, + 0, + camera_buffer, + 0, + matrix_size as u64, + ); } diff --git a/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs b/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs index 74188c934e..4326bf2da3 100644 --- a/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs @@ -63,6 +63,8 @@ where T: render_resource::RenderResources, { uniform_arrays: Vec>, + staging_buffer: Option, + staging_buffer_size: usize, _marker: PhantomData, } @@ -73,6 +75,8 @@ where fn default() -> Self { Self { uniform_arrays: Default::default(), + staging_buffer: Default::default(), + staging_buffer_size: 0, _marker: Default::default(), } } @@ -166,6 +170,7 @@ where let buffer = render_resource_context.create_buffer(BufferInfo { size: total_size, buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, + ..Default::default() }); buffer_array_status.current_item_capacity = new_capacity; @@ -181,7 +186,7 @@ where buffer_array_status.buffer = Some(buffer); } } - fn update_staging_buffer_offsets(&mut self) -> usize { + fn update_staging_buffer(&mut self, render_resource_context: &dyn RenderResourceContext) { let mut size = 0; for dynamic_buffer_array_status in self.uniform_arrays.iter_mut() { if let Some((_name, ref mut buffer_array_status)) = dynamic_buffer_array_status { @@ -190,7 +195,24 @@ where } } - size + if self.staging_buffer_size != size { + if let Some(staging_buffer) = self.staging_buffer { + render_resource_context.remove_buffer(staging_buffer); + } + + if size > 0 { + let staging_buffer = render_resource_context.create_buffer(BufferInfo { + buffer_usage: BufferUsage::COPY_SRC | BufferUsage::MAP_WRITE, + size, + ..Default::default() + }); + self.staging_buffer = Some(staging_buffer); + } else { + self.staging_buffer = None; + } + + self.staging_buffer_size = size; + } } fn setup_uniform_buffer_resources( @@ -412,7 +434,9 @@ fn render_resources_node_system( state .uniform_buffer_arrays .setup_buffer_arrays(render_resource_context, state.dynamic_uniforms); - let staging_buffer_size = state.uniform_buffer_arrays.update_staging_buffer_offsets(); + state + .uniform_buffer_arrays + .update_staging_buffer(render_resource_context); for (uniforms, draw, render_pipelines) in &mut query.iter() { if !draw.is_visible { @@ -426,28 +450,11 @@ fn render_resources_node_system( ) } - if staging_buffer_size == 0 { - let mut staging_buffer: [u8; 0] = []; - for (uniforms, draw, render_pipelines) in &mut query.iter() { - if !draw.is_visible { - return; - } - - state.uniform_buffer_arrays.setup_uniform_buffer_resources( - &uniforms, - state.dynamic_uniforms, - render_resource_context, - &mut render_pipelines.bindings, - &mut staging_buffer, - ); - } - } else { - let staging_buffer = render_resource_context.create_buffer_mapped( - BufferInfo { - buffer_usage: BufferUsage::COPY_SRC, - size: staging_buffer_size, - ..Default::default() - }, + if let Some(staging_buffer) = state.uniform_buffer_arrays.staging_buffer { + render_resource_context.map_buffer(staging_buffer); + render_resource_context.write_mapped_buffer( + staging_buffer, + 0..state.uniform_buffer_arrays.staging_buffer_size as u64, &mut |mut staging_buffer, _render_resource_context| { for (uniforms, draw, render_pipelines) in &mut query.iter() { if !draw.is_visible { @@ -464,11 +471,27 @@ fn render_resources_node_system( } }, ); + render_resource_context.unmap_buffer(staging_buffer); state .uniform_buffer_arrays .copy_staging_buffer_to_final_buffers(&mut state.command_queue, staging_buffer); - state.command_queue.free_buffer(staging_buffer); + } else { + // TODO: can we just remove this? + let mut staging_buffer: [u8; 0] = []; + for (uniforms, draw, render_pipelines) in &mut query.iter() { + if !draw.is_visible { + return; + } + + state.uniform_buffer_arrays.setup_uniform_buffer_resources( + &uniforms, + state.dynamic_uniforms, + render_resource_context, + &mut render_pipelines.bindings, + &mut staging_buffer, + ); + } } } @@ -576,7 +599,7 @@ fn asset_render_resources_node_system( state .uniform_buffer_arrays .setup_buffer_arrays(render_resource_context, state.dynamic_uniforms); - let staging_buffer_size = state.uniform_buffer_arrays.update_staging_buffer_offsets(); + state.uniform_buffer_arrays.update_staging_buffer(render_resource_context); for asset_handle in modified_assets.iter() { let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE); @@ -589,28 +612,11 @@ fn asset_render_resources_node_system( ); } - if staging_buffer_size == 0 { - let mut staging_buffer: [u8; 0] = []; - for asset_handle in modified_assets.iter() { - let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE); - let mut render_resource_bindings = - asset_render_resource_bindings.get_or_insert_mut(*asset_handle); - // TODO: only setup buffer if we haven't seen this handle before - state.uniform_buffer_arrays.setup_uniform_buffer_resources( - &asset, - state.dynamic_uniforms, - render_resource_context, - &mut render_resource_bindings, - &mut staging_buffer, - ); - } - } else { - let staging_buffer = render_resource_context.create_buffer_mapped( - BufferInfo { - buffer_usage: BufferUsage::COPY_SRC, - size: staging_buffer_size, - ..Default::default() - }, + if let Some(staging_buffer) = state.uniform_buffer_arrays.staging_buffer { + render_resource_context.map_buffer(staging_buffer); + render_resource_context.write_mapped_buffer( + staging_buffer, + 0..state.uniform_buffer_arrays.staging_buffer_size as u64, &mut |mut staging_buffer, _render_resource_context| { for asset_handle in modified_assets.iter() { let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE); @@ -627,11 +633,26 @@ fn asset_render_resources_node_system( } }, ); + render_resource_context.unmap_buffer(staging_buffer); state .uniform_buffer_arrays .copy_staging_buffer_to_final_buffers(&mut state.command_queue, staging_buffer); - state.command_queue.free_buffer(staging_buffer); + } else { + let mut staging_buffer: [u8; 0] = []; + for asset_handle in modified_assets.iter() { + let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE); + let mut render_resource_bindings = + asset_render_resource_bindings.get_or_insert_mut(*asset_handle); + // TODO: only setup buffer if we haven't seen this handle before + state.uniform_buffer_arrays.setup_uniform_buffer_resources( + &asset, + state.dynamic_uniforms, + render_resource_context, + &mut render_resource_bindings, + &mut staging_buffer, + ); + } } for (asset_handle, _draw, render_pipelines) in &mut query.iter() { diff --git a/crates/bevy_render/src/render_resource/buffer.rs b/crates/bevy_render/src/render_resource/buffer.rs index 7bfdfb8cab..04eb228087 100644 --- a/crates/bevy_render/src/render_resource/buffer.rs +++ b/crates/bevy_render/src/render_resource/buffer.rs @@ -13,6 +13,7 @@ impl BufferId { pub struct BufferInfo { pub size: usize, pub buffer_usage: BufferUsage, + pub mapped_at_creation: bool, } impl Default for BufferInfo { @@ -20,6 +21,7 @@ impl Default for BufferInfo { BufferInfo { size: 0, buffer_usage: BufferUsage::empty(), + mapped_at_creation: false, } } } diff --git a/crates/bevy_render/src/render_resource/shared_buffers.rs b/crates/bevy_render/src/render_resource/shared_buffers.rs index ebc34a97d5..eda84376e7 100644 --- a/crates/bevy_render/src/render_resource/shared_buffers.rs +++ b/crates/bevy_render/src/render_resource/shared_buffers.rs @@ -30,19 +30,26 @@ impl SharedBuffers { ) -> Option { if let Some(size) = render_resource.buffer_byte_len() { // PERF: this buffer will be slow - let staging_buffer = self.render_resource_context.create_buffer_mapped( - BufferInfo { - size, - buffer_usage: BufferUsage::COPY_SRC, - }, + let staging_buffer = self.render_resource_context.create_buffer(BufferInfo { + size, + buffer_usage: BufferUsage::COPY_SRC | BufferUsage::MAP_WRITE, + mapped_at_creation: true, + }); + + self.render_resource_context.write_mapped_buffer( + staging_buffer, + 0..size as u64, &mut |data, _renderer| { render_resource.write_buffer_bytes(data); }, ); + self.render_resource_context.unmap_buffer(staging_buffer); + let destination_buffer = self.render_resource_context.create_buffer(BufferInfo { size, buffer_usage: BufferUsage::COPY_DST | buffer_usage, + ..Default::default() }); let mut command_queue = self.command_queue.write().unwrap(); diff --git a/crates/bevy_render/src/renderer/headless_render_resource_context.rs b/crates/bevy_render/src/renderer/headless_render_resource_context.rs index c3e1fc8a4a..74e73045e2 100644 --- a/crates/bevy_render/src/renderer/headless_render_resource_context.rs +++ b/crates/bevy_render/src/renderer/headless_render_resource_context.rs @@ -9,6 +9,7 @@ use bevy_asset::{Assets, Handle, HandleUntyped}; use bevy_window::{Window, WindowId}; use std::{ collections::HashMap, + ops::Range, sync::{Arc, RwLock}, }; @@ -52,15 +53,18 @@ impl RenderResourceContext for HeadlessRenderResourceContext { self.add_buffer_info(buffer, buffer_info); buffer } - fn create_buffer_mapped( + fn write_mapped_buffer( &self, - buffer_info: BufferInfo, - setup_data: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), - ) -> BufferId { - let mut buffer = vec![0; buffer_info.size]; - setup_data(&mut buffer, self); - BufferId::new() + id: BufferId, + _range: Range, + write: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), + ) { + let size = self.buffer_info.read().unwrap().get(&id).unwrap().size; + let mut buffer = vec![0; size]; + write(&mut buffer, self); } + fn map_buffer(&self, _id: BufferId) {} + fn unmap_buffer(&self, _id: BufferId) {} fn create_buffer_with_data(&self, buffer_info: BufferInfo, _data: &[u8]) -> BufferId { let buffer = BufferId::new(); self.add_buffer_info(buffer, buffer_info); diff --git a/crates/bevy_render/src/renderer/render_resource_context.rs b/crates/bevy_render/src/renderer/render_resource_context.rs index d4521e3124..2286ad35be 100644 --- a/crates/bevy_render/src/renderer/render_resource_context.rs +++ b/crates/bevy_render/src/renderer/render_resource_context.rs @@ -7,6 +7,7 @@ use crate::{ use bevy_asset::{Assets, Handle, HandleUntyped}; use bevy_window::{Window, WindowId}; use downcast_rs::{impl_downcast, Downcast}; +use std::ops::Range; pub trait RenderResourceContext: Downcast + Send + Sync + 'static { fn create_swap_chain(&self, window: &Window); @@ -17,11 +18,20 @@ pub trait RenderResourceContext: Downcast + Send + Sync + 'static { fn create_texture(&self, texture_descriptor: TextureDescriptor) -> TextureId; fn create_buffer(&self, buffer_info: BufferInfo) -> BufferId; // TODO: remove RenderResourceContext here - fn create_buffer_mapped( + fn write_mapped_buffer( &self, - buffer_info: BufferInfo, - setup_data: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), - ) -> BufferId; + id: BufferId, + range: Range, + write: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), + ); + fn map_buffer( + &self, + id: BufferId, + ); + fn unmap_buffer( + &self, + id: BufferId, + ); fn create_buffer_with_data(&self, buffer_info: BufferInfo, data: &[u8]) -> BufferId; fn create_shader_module(&self, shader_handle: Handle, shaders: &Assets); fn create_shader_module_from_source(&self, shader_handle: Handle, shader: &Shader); diff --git a/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs b/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs index 861de68546..57c8230a88 100644 --- a/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs +++ b/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs @@ -15,7 +15,7 @@ use bevy_render::{ texture::{Extent3d, SamplerDescriptor, TextureDescriptor}, }; use bevy_window::{Window, WindowId}; -use std::sync::Arc; +use std::{ops::Range, sync::Arc}; #[derive(Clone)] pub struct WgpuRenderResourceContext { @@ -167,43 +167,12 @@ impl RenderResourceContext for WgpuRenderResourceContext { label: None, size: buffer_info.size as u64, usage: buffer_info.buffer_usage.wgpu_into(), - mapped_at_creation: false, + mapped_at_creation: buffer_info.mapped_at_creation, }); let id = BufferId::new(); buffer_infos.insert(id, buffer_info); - buffers.insert(id, buffer); - id - } - - fn create_buffer_mapped( - &self, - buffer_info: BufferInfo, - setup_data: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), - ) -> BufferId { - let usage: wgpu::BufferUsage = buffer_info.buffer_usage.wgpu_into(); - let buffer = self.device.create_buffer(&wgpu::BufferDescriptor { - size: buffer_info.size as u64, - usage: usage | wgpu::BufferUsage::MAP_WRITE, - label: None, - mapped_at_creation: false, - }); - let buffer_slice = buffer.slice(..); - let data = buffer_slice.map_async(wgpu::MapMode::Write); - self.device.poll(wgpu::Maintain::Wait); - if let Ok(()) = pollster::block_on(data) { - let mut data = buffer_slice.get_mapped_range_mut(); - setup_data(&mut data, self); - } else { - panic!("failed to map buffer to host"); - } - - buffer.unmap(); - let id = BufferId::new(); - let mut buffer_infos = self.resources.buffer_infos.write().unwrap(); - let mut buffers = self.resources.buffers.write().unwrap(); - buffer_infos.insert(id, buffer_info); - buffers.insert(id, buffer); + buffers.insert(id, Arc::new(buffer)); id } @@ -219,7 +188,7 @@ impl RenderResourceContext for WgpuRenderResourceContext { let id = BufferId::new(); buffer_infos.insert(id, buffer_info); - buffers.insert(id, buffer); + buffers.insert(id, Arc::new(buffer)); id } @@ -522,4 +491,34 @@ impl RenderResourceContext for WgpuRenderResourceContext { .get(&buffer) .cloned() } + fn write_mapped_buffer( + &self, + id: BufferId, + range: Range, + write: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), + ) { + let buffer = { + let buffers = self.resources.buffers.read().unwrap(); + buffers.get(&id).unwrap().clone() + }; + let buffer_slice = buffer.slice(range); + let mut data = buffer_slice.get_mapped_range_mut(); + write(&mut data, self); + } + + fn map_buffer(&self, id: BufferId) { + let buffers = self.resources.buffers.read().unwrap(); + let buffer = buffers.get(&id).unwrap(); + let buffer_slice = buffer.slice(..); + let data = buffer_slice.map_async(wgpu::MapMode::Write); + self.device.poll(wgpu::Maintain::Wait); + if let Err(_) = pollster::block_on(data) { + panic!("failed to map buffer to host"); + } + } + fn unmap_buffer(&self, id: BufferId) { + let buffers = self.resources.buffers.read().unwrap(); + let buffer = buffers.get(&id).unwrap(); + buffer.unmap(); + } } diff --git a/crates/bevy_wgpu/src/wgpu_resources.rs b/crates/bevy_wgpu/src/wgpu_resources.rs index 161d5a963c..32100b24ed 100644 --- a/crates/bevy_wgpu/src/wgpu_resources.rs +++ b/crates/bevy_wgpu/src/wgpu_resources.rs @@ -39,7 +39,7 @@ pub struct WgpuBindGroupInfo { /// Single threaded implementations don't need to worry about these lifetimes constraints at all. RenderPasses can use a RenderContext's /// WgpuResources directly. RenderContext already has a lifetime greater than the RenderPass. pub struct WgpuResourcesReadLock<'a> { - pub buffers: RwLockReadGuard<'a, HashMap>, + pub buffers: RwLockReadGuard<'a, HashMap>>, pub textures: RwLockReadGuard<'a, HashMap>, pub swap_chain_frames: RwLockReadGuard<'a, HashMap>, pub render_pipelines: @@ -61,7 +61,7 @@ impl<'a> WgpuResourcesReadLock<'a> { /// Stores read only references to WgpuResource collections. See WgpuResourcesReadLock docs for context on why this exists pub struct WgpuResourceRefs<'a> { - pub buffers: &'a HashMap, + pub buffers: &'a HashMap>, pub textures: &'a HashMap, pub swap_chain_frames: &'a HashMap, pub render_pipelines: &'a HashMap, wgpu::RenderPipeline>, @@ -75,7 +75,7 @@ pub struct WgpuResources { pub window_surfaces: Arc>>, pub window_swap_chains: Arc>>, pub swap_chain_frames: Arc>>, - pub buffers: Arc>>, + pub buffers: Arc>>>, pub texture_views: Arc>>, pub textures: Arc>>, pub samplers: Arc>>,