From a1837760398827fa15f6cdb76c5858f2f1c23e4e Mon Sep 17 00:00:00 2001 From: Renato Caldas Date: Wed, 20 Jan 2021 23:59:58 +0000 Subject: [PATCH] Add support for mapping buffers for reading. --- crates/bevy_pbr/src/render_graph/lights_node.rs | 4 ++-- .../src/render_graph/nodes/camera_node.rs | 4 ++-- .../src/render_graph/nodes/render_resources_node.rs | 6 +++--- .../src/renderer/headless_render_resource_context.rs | 6 ++++-- .../src/renderer/render_resource/buffer.rs | 6 ++++++ .../src/renderer/render_resource/shared_buffers.rs | 4 ++-- .../src/renderer/render_resource_context.rs | 6 ++++-- .../src/renderer/wgpu_render_resource_context.rs | 12 ++++++++---- 8 files changed, 31 insertions(+), 17 deletions(-) diff --git a/crates/bevy_pbr/src/render_graph/lights_node.rs b/crates/bevy_pbr/src/render_graph/lights_node.rs index d327d56c2fffe..94ad213f4fbfc 100644 --- a/crates/bevy_pbr/src/render_graph/lights_node.rs +++ b/crates/bevy_pbr/src/render_graph/lights_node.rs @@ -9,7 +9,7 @@ use bevy_ecs::{ use bevy_render::{ render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, renderer::{ - BufferId, BufferInfo, BufferUsage, RenderContext, RenderResourceBinding, + BufferId, BufferInfo, BufferMapMode, BufferUsage, RenderContext, RenderResourceBinding, RenderResourceBindings, RenderResourceContext, }, }; @@ -103,7 +103,7 @@ pub fn lights_node_system( return; } - render_resource_context.map_buffer(staging_buffer); + render_resource_context.map_buffer(staging_buffer, BufferMapMode::Write); } else { let buffer = render_resource_context.create_buffer(BufferInfo { size: max_light_uniform_size, 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 245b890d92042..54d119c13a4b4 100644 --- a/crates/bevy_render/src/render_graph/nodes/camera_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/camera_node.rs @@ -2,7 +2,7 @@ use crate::{ camera::{ActiveCameras, Camera}, render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, renderer::{ - BufferId, BufferInfo, BufferUsage, RenderContext, RenderResourceBinding, + BufferId, BufferInfo, BufferMapMode, BufferUsage, RenderContext, RenderResourceBinding, RenderResourceBindings, RenderResourceContext, }, }; @@ -87,7 +87,7 @@ pub fn camera_node_system( }; let staging_buffer = if let Some(staging_buffer) = state.staging_buffer { - render_resource_context.map_buffer(staging_buffer); + render_resource_context.map_buffer(staging_buffer, BufferMapMode::Write); staging_buffer } else { let size = std::mem::size_of::<[[f32; 4]; 4]>(); 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 68422596b07ff..141d8bfc9d757 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 @@ -3,7 +3,7 @@ use crate::{ prelude::Visible, render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, renderer::{ - self, BufferInfo, BufferUsage, RenderContext, RenderResourceBinding, + self, BufferInfo, BufferMapMode, BufferUsage, RenderContext, RenderResourceBinding, RenderResourceBindings, RenderResourceContext, RenderResourceHints, }, texture, @@ -490,7 +490,7 @@ fn render_resources_node_system( uniform_buffer_arrays.resize_staging_buffer(render_resource_context); if let Some(staging_buffer) = state.uniform_buffer_arrays.staging_buffer { - render_resource_context.map_buffer(staging_buffer); + render_resource_context.map_buffer(staging_buffer, BufferMapMode::Write); render_resource_context.write_mapped_buffer( staging_buffer, 0..state.uniform_buffer_arrays.staging_buffer_size as u64, @@ -703,7 +703,7 @@ fn asset_render_resources_node_system( uniform_buffer_arrays.resize_staging_buffer(render_resource_context); if let Some(staging_buffer) = state.uniform_buffer_arrays.staging_buffer { - render_resource_context.map_buffer(staging_buffer); + render_resource_context.map_buffer(staging_buffer, BufferMapMode::Write); render_resource_context.write_mapped_buffer( staging_buffer, 0..state.uniform_buffer_arrays.staging_buffer_size as u64, 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 ed182a51bb1d3..987119849cf2c 100644 --- a/crates/bevy_render/src/renderer/headless_render_resource_context.rs +++ b/crates/bevy_render/src/renderer/headless_render_resource_context.rs @@ -1,7 +1,9 @@ use super::RenderResourceContext; use crate::{ pipeline::{BindGroupDescriptorId, PipelineDescriptor}, - renderer::{BindGroup, BufferId, BufferInfo, RenderResourceId, SamplerId, TextureId}, + renderer::{ + BindGroup, BufferId, BufferInfo, BufferMapMode, RenderResourceId, SamplerId, TextureId, + }, shader::{Shader, ShaderError}, texture::{SamplerDescriptor, TextureDescriptor}, }; @@ -66,7 +68,7 @@ impl RenderResourceContext for HeadlessRenderResourceContext { write(&mut buffer, self); } - fn map_buffer(&self, _id: BufferId) {} + fn map_buffer(&self, _id: BufferId, _mode: BufferMapMode) {} fn unmap_buffer(&self, _id: BufferId) {} diff --git a/crates/bevy_render/src/renderer/render_resource/buffer.rs b/crates/bevy_render/src/renderer/render_resource/buffer.rs index c254e228f17d1..00252ffa9e2d6 100644 --- a/crates/bevy_render/src/renderer/render_resource/buffer.rs +++ b/crates/bevy_render/src/renderer/render_resource/buffer.rs @@ -43,3 +43,9 @@ bitflags::bitflags! { const INDIRECT = 256; } } + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum BufferMapMode { + Read, + Write, +} diff --git a/crates/bevy_render/src/renderer/render_resource/shared_buffers.rs b/crates/bevy_render/src/renderer/render_resource/shared_buffers.rs index bf2e399e19938..82dfc231bb800 100644 --- a/crates/bevy_render/src/renderer/render_resource/shared_buffers.rs +++ b/crates/bevy_render/src/renderer/render_resource/shared_buffers.rs @@ -1,7 +1,7 @@ use super::{BufferId, BufferInfo, RenderResource, RenderResourceBinding}; use crate::{ render_graph::CommandQueue, - renderer::{BufferUsage, RenderContext, RenderResourceContext}, + renderer::{BufferMapMode, BufferUsage, RenderContext, RenderResourceContext}, }; use bevy_ecs::{Res, ResMut}; @@ -115,7 +115,7 @@ impl SharedBuffers { } if let Some(staging_buffer) = self.staging_buffer { - render_resource_context.map_buffer(staging_buffer); + render_resource_context.map_buffer(staging_buffer, BufferMapMode::Write); } } diff --git a/crates/bevy_render/src/renderer/render_resource_context.rs b/crates/bevy_render/src/renderer/render_resource_context.rs index 365595fac7816..7d6a6018c7686 100644 --- a/crates/bevy_render/src/renderer/render_resource_context.rs +++ b/crates/bevy_render/src/renderer/render_resource_context.rs @@ -1,6 +1,8 @@ use crate::{ pipeline::{BindGroupDescriptorId, PipelineDescriptor, PipelineLayout}, - renderer::{BindGroup, BufferId, BufferInfo, RenderResourceId, SamplerId, TextureId}, + renderer::{ + BindGroup, BufferId, BufferInfo, BufferMapMode, RenderResourceId, SamplerId, TextureId, + }, shader::{Shader, ShaderError, ShaderLayout, ShaderStages}, texture::{SamplerDescriptor, TextureDescriptor}, }; @@ -24,7 +26,7 @@ pub trait RenderResourceContext: Downcast + Send + Sync + 'static { range: Range, write: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), ); - fn map_buffer(&self, id: BufferId); + fn map_buffer(&self, id: BufferId, mode: BufferMapMode); 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); 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 bd1be8db72260..27afefff69f82 100644 --- a/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs +++ b/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs @@ -9,8 +9,8 @@ use bevy_render::{ BindGroupDescriptor, BindGroupDescriptorId, BindingShaderStage, PipelineDescriptor, }, renderer::{ - BindGroup, BufferId, BufferInfo, RenderResourceBinding, RenderResourceContext, - RenderResourceId, SamplerId, TextureId, + BindGroup, BufferId, BufferInfo, BufferMapMode, RenderResourceBinding, + RenderResourceContext, RenderResourceId, SamplerId, TextureId, }, shader::{glsl_to_spirv, Shader, ShaderError, ShaderSource}, texture::{Extent3d, SamplerDescriptor, TextureDescriptor}, @@ -622,11 +622,15 @@ impl RenderResourceContext for WgpuRenderResourceContext { write(&mut data, self); } - fn map_buffer(&self, id: BufferId) { + fn map_buffer(&self, id: BufferId, mode: BufferMapMode) { let buffers = self.resources.buffers.read(); let buffer = buffers.get(&id).unwrap(); let buffer_slice = buffer.slice(..); - let data = buffer_slice.map_async(wgpu::MapMode::Write); + let wgpu_mode = match mode { + BufferMapMode::Read => wgpu::MapMode::Read, + BufferMapMode::Write => wgpu::MapMode::Write, + }; + let data = buffer_slice.map_async(wgpu_mode); self.device.poll(wgpu::Maintain::Wait); if future::block_on(data).is_err() { panic!("Failed to map buffer to host.");