From 40fccd29ca1de986c14275cb41251b211ba4d353 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Thu, 7 Oct 2021 19:24:48 +0000 Subject: [PATCH] Use RenderQueue in BufferVec (#2847) Using RenderQueue in BufferVec allows removal of the staging buffer entirely, as well as removal of the SpriteNode. Co-authored-by: Carter Anderson --- .../src/render_resource/buffer_vec.rs | 54 +++++-------------- pipelined/bevy_sprite2/src/lib.rs | 9 +--- pipelined/bevy_sprite2/src/render/mod.rs | 29 ++-------- 3 files changed, 19 insertions(+), 73 deletions(-) diff --git a/pipelined/bevy_render2/src/render_resource/buffer_vec.rs b/pipelined/bevy_render2/src/render_resource/buffer_vec.rs index 274cfb225f..12056c2961 100644 --- a/pipelined/bevy_render2/src/render_resource/buffer_vec.rs +++ b/pipelined/bevy_render2/src/render_resource/buffer_vec.rs @@ -1,10 +1,12 @@ -use crate::{render_resource::Buffer, renderer::RenderDevice}; +use crate::{ + render_resource::Buffer, + renderer::{RenderDevice, RenderQueue}, +}; use bevy_core::{cast_slice, Pod}; use wgpu::BufferUsage; pub struct BufferVec { values: Vec, - staging_buffer: Option, buffer: Option, capacity: usize, item_size: usize, @@ -15,7 +17,6 @@ impl Default for BufferVec { fn default() -> Self { Self { values: Vec::new(), - staging_buffer: None, buffer: None, capacity: 0, buffer_usage: BufferUsage::all(), @@ -31,10 +32,6 @@ impl BufferVec { ..Default::default() } } - #[inline] - pub fn staging_buffer(&self) -> Option<&Buffer> { - self.staging_buffer.as_ref() - } #[inline] pub fn buffer(&self) -> Option<&Buffer> { @@ -47,10 +44,10 @@ impl BufferVec { } pub fn push(&mut self, value: T) -> usize { - if self.values.len() < self.capacity { - let index = self.values.len(); + let len = self.values.len(); + if len < self.capacity { self.values.push(value); - index + len } else { panic!( "Cannot push value because capacity of {} has been reached", @@ -62,16 +59,10 @@ impl BufferVec { pub fn reserve(&mut self, capacity: usize, device: &RenderDevice) { if capacity > self.capacity { self.capacity = capacity; - let size = (self.item_size * capacity) as wgpu::BufferAddress; - self.staging_buffer = Some(device.create_buffer(&wgpu::BufferDescriptor { - label: None, - size, - usage: BufferUsage::COPY_SRC | BufferUsage::MAP_WRITE, - mapped_at_creation: false, - })); + let size = self.item_size * capacity; self.buffer = Some(device.create_buffer(&wgpu::BufferDescriptor { label: None, - size, + size: size as wgpu::BufferAddress, usage: BufferUsage::COPY_DST | self.buffer_usage, mapped_at_creation: false, })); @@ -83,28 +74,11 @@ impl BufferVec { self.reserve(capacity, device); } - pub fn write_to_staging_buffer(&self, render_device: &RenderDevice) { - if let Some(staging_buffer) = &self.staging_buffer { - let end = (self.values.len() * self.item_size) as u64; - let slice = staging_buffer.slice(0..end); - render_device.map_buffer(&slice, wgpu::MapMode::Write); - { - let mut data = slice.get_mapped_range_mut(); - let bytes: &[u8] = cast_slice(&self.values); - data.copy_from_slice(bytes); - } - staging_buffer.unmap(); - } - } - pub fn write_to_buffer(&self, command_encoder: &mut wgpu::CommandEncoder) { - if let (Some(staging_buffer), Some(uniform_buffer)) = (&self.staging_buffer, &self.buffer) { - command_encoder.copy_buffer_to_buffer( - staging_buffer, - 0, - uniform_buffer, - 0, - (self.values.len() * self.item_size) as u64, - ); + pub fn write_buffer(&mut self, queue: &RenderQueue) { + if let Some(buffer) = &self.buffer { + let range = 0..self.item_size * self.values.len(); + let bytes: &[u8] = cast_slice(&self.values); + queue.write_buffer(buffer, 0, &bytes[range]); } } diff --git a/pipelined/bevy_sprite2/src/lib.rs b/pipelined/bevy_sprite2/src/lib.rs index 4d443d2b69..68596b9253 100644 --- a/pipelined/bevy_sprite2/src/lib.rs +++ b/pipelined/bevy_sprite2/src/lib.rs @@ -17,9 +17,7 @@ pub use texture_atlas_builder::*; use bevy_app::prelude::*; use bevy_asset::AddAsset; use bevy_core_pipeline::Transparent2d; -use bevy_render2::{ - render_graph::RenderGraph, render_phase::DrawFunctions, RenderApp, RenderStage, -}; +use bevy_render2::{render_phase::DrawFunctions, RenderApp, RenderStage}; #[derive(Default)] pub struct SpritePlugin; @@ -44,10 +42,5 @@ impl Plugin for SpritePlugin { .unwrap() .write() .add(draw_sprite); - let mut graph = render_app.world.get_resource_mut::().unwrap(); - graph.add_node("sprite", SpriteNode); - graph - .add_node_edge("sprite", bevy_core_pipeline::node::MAIN_PASS_DEPENDENCIES) - .unwrap(); } } diff --git a/pipelined/bevy_sprite2/src/render/mod.rs b/pipelined/bevy_sprite2/src/render/mod.rs index 6ab413a061..47d8d81492 100644 --- a/pipelined/bevy_sprite2/src/render/mod.rs +++ b/pipelined/bevy_sprite2/src/render/mod.rs @@ -12,10 +12,9 @@ use bevy_math::{Mat4, Vec2, Vec3, Vec4Swizzles}; use bevy_render2::{ mesh::{shape::Quad, Indices, Mesh, VertexAttributeValues}, render_asset::RenderAssets, - render_graph::{Node, NodeRunError, RenderGraphContext}, render_phase::{Draw, DrawFunctions, RenderPhase, TrackedRenderPass}, render_resource::*, - renderer::{RenderContext, RenderDevice}, + renderer::{RenderDevice, RenderQueue}, shader::Shader, texture::{BevyDefault, Image}, view::{ViewUniformOffset, ViewUniforms}, @@ -246,6 +245,7 @@ impl Default for SpriteMeta { pub fn prepare_sprites( render_device: Res, + render_queue: Res, mut sprite_meta: ResMut, mut extracted_sprites: Query<&mut ExtractedSprite>, ) { @@ -312,8 +312,8 @@ pub fn prepare_sprites( } } - sprite_meta.vertices.write_to_staging_buffer(&render_device); - sprite_meta.indices.write_to_staging_buffer(&render_device); + sprite_meta.vertices.write_buffer(&render_queue); + sprite_meta.indices.write_buffer(&render_queue); } #[derive(Default)] @@ -375,27 +375,6 @@ pub fn queue_sprites( } } -// TODO: this logic can be moved to prepare_sprites once wgpu::Queue is exposed directly -pub struct SpriteNode; - -impl Node for SpriteNode { - fn run( - &self, - _graph: &mut RenderGraphContext, - render_context: &mut RenderContext, - world: &World, - ) -> Result<(), NodeRunError> { - let sprite_buffers = world.get_resource::().unwrap(); - sprite_buffers - .vertices - .write_to_buffer(&mut render_context.command_encoder); - sprite_buffers - .indices - .write_to_buffer(&mut render_context.command_encoder); - Ok(()) - } -} - pub struct DrawSprite { params: SystemState<( SRes,