diff --git a/bevy_render/src/lib.rs b/bevy_render/src/lib.rs index 8c1e342e90..5a6487c381 100644 --- a/bevy_render/src/lib.rs +++ b/bevy_render/src/lib.rs @@ -41,7 +41,7 @@ use self::{ render_resource::{ entity_render_resource_assignments_system, resource_providers::{ - Camera2dResourceProvider, CameraResourceProvider, LightResourceProvider, + LightResourceProvider, UniformResourceProvider, }, AssetBatchers, EntityRenderResourceAssignments, RenderResourceAssignments, @@ -50,12 +50,11 @@ use self::{ texture::Texture, }; -use bevy_app::{stage, AppBuilder, AppPlugin, GetEventReader}; +use bevy_app::{stage, AppBuilder, AppPlugin}; use bevy_asset::AssetStorage; use bevy_transform::prelude::LocalToWorld; -use bevy_window::WindowResized; -use render_resource::resource_providers::{CameraNode, mesh_resource_provider_system}; -use render_graph_2::RenderGraph2; +use render_resource::resource_providers::{mesh_resource_provider_system}; +use render_graph_2::{nodes::{Camera2dNode, CameraNode}, RenderGraph2}; pub static RENDER_RESOURCE_STAGE: &str = "render_resource"; pub static RENDER_STAGE: &str = "render"; @@ -78,9 +77,6 @@ impl RenderPlugin { .add_draw_target(AssignedBatchesDrawTarget::default()) .add_draw_target(AssignedMeshesDrawTarget::default()) .add_draw_target(UiDrawTarget::default()) - .add_resource_provider(Camera2dResourceProvider::new( - resources.get_event_reader::(), - )) .add_resource_provider(LightResourceProvider::new(10)) .add_resource_provider(UniformResourceProvider::::new(true)) .add_resource_provider(UniformResourceProvider::::new(true)) @@ -93,6 +89,7 @@ impl AppPlugin for RenderPlugin { fn build(&self, app: &mut AppBuilder) { let mut render_graph = RenderGraph2::default(); render_graph.add_system_node(CameraNode::default(), app.resources_mut()); + render_graph.add_system_node(Camera2dNode::default(), app.resources_mut()); let mut asset_batchers = AssetBatchers::default(); asset_batchers.batch_types2::(); app.add_stage_after(stage::POST_UPDATE, RENDER_RESOURCE_STAGE) diff --git a/bevy_render/src/render_graph_2/mod.rs b/bevy_render/src/render_graph_2/mod.rs index fe79efb9f0..ab23c679b9 100644 --- a/bevy_render/src/render_graph_2/mod.rs +++ b/bevy_render/src/render_graph_2/mod.rs @@ -1,3 +1,5 @@ +pub mod nodes; + use crate::{ render_resource::{RenderResource, ResourceInfo}, renderer_2::RenderContext, @@ -76,37 +78,124 @@ impl NodeId { } } +pub struct ResourceBinding { + pub resource: Option, + pub slot: ResourceSlot, +} + +#[derive(Default)] +pub struct ResourceBindings { + bindings: Vec, +} + +impl ResourceBindings { + pub fn set(&mut self, index: usize, resource: RenderResource) { + self.bindings[index].resource = Some(resource); + } + + pub fn set_named(&mut self, name: &str, resource: RenderResource) { + let binding = self + .bindings + .iter_mut() + .find(|b| b.slot.name == name) + .expect("Name not found"); + binding.resource = Some(resource); + } + + pub fn get(&self, index: usize) -> Option { + self.bindings + .get(index) + .and_then(|binding| binding.resource) + } + + pub fn get_named(&self, name: &str) -> Option { + self.bindings + .iter() + .find(|b| b.slot.name == name) + .and_then(|binding| binding.resource) + } +} + +impl From<&ResourceSlot> for ResourceBinding { + fn from(slot: &ResourceSlot) -> Self { + ResourceBinding { + resource: None, + slot: slot.clone(), + } + } +} + +impl From<&[ResourceSlot]> for ResourceBindings { + fn from(slots: &[ResourceSlot]) -> Self { + ResourceBindings { + bindings: slots + .iter() + .map(|s| s.into()) + .collect::>(), + } + } +} + +#[derive(Clone)] pub struct ResourceSlot { - name: Option, + name: &'static str, resource_type: ResourceInfo, } -pub struct ResourceSlotBinding { - resource: RenderResource, -} - -pub struct NodeDescriptor { - pub inputs: Vec, - pub outputs: Vec, +impl ResourceSlot { + pub const fn new(name: &'static str, resource_type: ResourceInfo) -> Self { + ResourceSlot { + name, + resource_type, + } + } } pub trait Node: Send + Sync + 'static { - fn descriptor(&self) -> &NodeDescriptor; + fn input(&self) -> &[ResourceSlot] { + &[] + } + + fn output(&self) -> &[ResourceSlot] { + &[] + } + fn update( &mut self, world: &World, resources: &Resources, render_context: &mut dyn RenderContext, + input: &ResourceBindings, + output: &mut ResourceBindings, ); } +pub struct NodeState { + pub node: Box, + pub input: ResourceBindings, + pub output: ResourceBindings, +} + +impl NodeState { + pub fn new(node: T) -> Self + where + T: Node, + { + NodeState { + input: ResourceBindings::from(node.input()), + output: ResourceBindings::from(node.output()), + node: Box::new(node), + } + } +} + pub trait SystemNode: Node { fn get_system(&self, resources: &mut Resources) -> Box; } #[derive(Default)] pub struct RenderGraph2 { - nodes: HashMap>, + nodes: HashMap, new_systems: Vec>, system_executor: Option, } @@ -117,7 +206,7 @@ impl RenderGraph2 { T: Node + 'static, { let id = NodeId::new(); - self.nodes.insert(id, Box::new(node)); + self.nodes.insert(id, NodeState::new(node)); id } @@ -127,14 +216,10 @@ impl RenderGraph2 { { let id = NodeId::new(); self.new_systems.push(node.get_system(resources)); - self.nodes.insert(id, Box::new(node)); + self.nodes.insert(id, NodeState::new(node)); id } - pub fn get_schedule(&mut self) -> impl Iterator> { - self.nodes.values_mut() - } - pub fn take_executor(&mut self) -> Option { // rebuild executor if there are new systems if self.new_systems.len() > 0 { @@ -157,3 +242,54 @@ impl RenderGraph2 { self.system_executor = Some(executor); } } + +#[derive(Default)] +pub struct Stage<'a> { + ordered_jobs: Vec>, +} + +impl<'a> Stage<'a> { + pub fn add(&mut self, job: OrderedJob<'a>) { + self.ordered_jobs.push(job); + } + + pub fn iter_mut(&mut self) -> impl Iterator> { + self.ordered_jobs.iter_mut() + } +} + +#[derive(Default)] +pub struct OrderedJob<'a> { + node_states: Vec<&'a mut NodeState>, +} + +impl<'a> OrderedJob<'a> { + pub fn add(&mut self, node_state: &'a mut NodeState) { + self.node_states.push(node_state); + } + + pub fn iter_mut(&mut self) -> impl Iterator { + self.node_states.iter_mut() + } +} + +pub trait RenderGraphScheduler { + fn get_stages<'a>(&mut self, render_graph: &'a mut RenderGraph2) -> Vec>; +} + +#[derive(Default)] +pub struct LinearScheduler; + +impl RenderGraphScheduler for LinearScheduler { + fn get_stages<'a>(&mut self, render_graph: &'a mut RenderGraph2) -> Vec> { + let mut stage = Stage::default(); + let mut job = OrderedJob::default(); + for node_state in render_graph.nodes.values_mut() { + job.add(node_state); + } + + stage.ordered_jobs.push(job); + + vec![stage] + } +} \ No newline at end of file diff --git a/bevy_render/src/render_graph_2/nodes/camera2d_node.rs b/bevy_render/src/render_graph_2/nodes/camera2d_node.rs new file mode 100644 index 0000000000..5b658651f0 --- /dev/null +++ b/bevy_render/src/render_graph_2/nodes/camera2d_node.rs @@ -0,0 +1,100 @@ +use bevy_app::{Events, GetEventReader}; +use bevy_window::WindowResized; + +use crate::{ + camera::{ActiveCamera2d, Camera}, + render_graph_2::{CommandQueue, Node, SystemNode, ResourceBindings}, + render_resource::{resource_name, BufferInfo, BufferUsage, RenderResourceAssignments}, + renderer_2::{GlobalRenderResourceContext, RenderContext}, +}; + +use bevy_transform::components::LocalToWorld; +use legion::prelude::*; +use zerocopy::AsBytes; + +#[derive(Default)] +pub struct Camera2dNode { + command_queue: CommandQueue, +} + +impl Node for Camera2dNode { + fn update( + &mut self, + _world: &World, + _resources: &Resources, + render_context: &mut dyn RenderContext, + _input: &ResourceBindings, + _output: &mut ResourceBindings, + ) { + self.command_queue.execute(render_context); + } +} + +impl SystemNode for Camera2dNode { + fn get_system(&self, resources: &mut Resources) -> Box { + let mut camera_buffer = None; + let mut tmp_buffer = None; + let mut window_resized_event_reader = resources.get_event_reader::(); + let mut command_queue = self.command_queue.clone(); + SystemBuilder::new("camera_resource_provider") + .read_resource::() + // TODO: this write on RenderResourceAssignments will prevent this system from running in parallel with other systems that do the same + .write_resource::() + .read_resource::>() + .with_query(<(Read, Read, Read)>::query()) + .build( + move |_, + world, + ( + render_resource_context, + ref mut render_resource_assignments, + window_resized_events, + ), + query| { + let render_resources = &render_resource_context.context; + if camera_buffer.is_none() { + let buffer = render_resources.create_buffer(BufferInfo { + size: std::mem::size_of::<[[f32; 4]; 4]>(), + buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, + ..Default::default() + }); + render_resource_assignments.set(resource_name::uniform::CAMERA2D, buffer); + camera_buffer = Some(buffer); + } + + let primary_window_resized_event = window_resized_events + .find_latest(&mut window_resized_event_reader, |event| event.is_primary); + if let Some(_) = primary_window_resized_event { + let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>(); + for (camera, local_to_world, _) in query.iter(world) { + let camera_matrix: [[f32; 4]; 4] = + (camera.view_matrix * local_to_world.0).to_cols_array_2d(); + + if let Some(old_tmp_buffer) = tmp_buffer { + render_resources.remove_buffer(old_tmp_buffer); + } + + tmp_buffer = Some(render_resources.create_buffer_mapped( + BufferInfo { + size: matrix_size, + buffer_usage: BufferUsage::COPY_SRC, + ..Default::default() + }, + &mut |data, _renderer| { + data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes()); + }, + )); + + command_queue.copy_buffer_to_buffer( + tmp_buffer.unwrap(), + 0, + camera_buffer.unwrap(), + 0, + matrix_size as u64, + ); + } + } + }, + ) + } +} diff --git a/bevy_render/src/render_resource/resource_providers/camera_resource_provider.rs b/bevy_render/src/render_graph_2/nodes/camera_node.rs similarity index 92% rename from bevy_render/src/render_resource/resource_providers/camera_resource_provider.rs rename to bevy_render/src/render_graph_2/nodes/camera_node.rs index 3599a21c9d..6860ac36ce 100644 --- a/bevy_render/src/render_resource/resource_providers/camera_resource_provider.rs +++ b/bevy_render/src/render_graph_2/nodes/camera_node.rs @@ -1,7 +1,5 @@ -use bevy_window::WindowResized; - use crate::{ - render_graph_2::{CommandQueue, Node, NodeDescriptor, SystemNode}, + render_graph_2::{CommandQueue, Node, SystemNode, ResourceBindings}, render_resource::{resource_name, BufferInfo, BufferUsage, RenderResourceAssignments}, renderer_2::{GlobalRenderResourceContext, RenderContext}, ActiveCamera, Camera, @@ -10,8 +8,8 @@ use crate::{ use bevy_app::{Events, GetEventReader}; use bevy_transform::prelude::*; use legion::prelude::*; -use once_cell::sync::Lazy; use zerocopy::AsBytes; +use bevy_window::WindowResized; #[derive(Default)] pub struct CameraNode { @@ -19,19 +17,13 @@ pub struct CameraNode { } impl Node for CameraNode { - fn descriptor(&self) -> &NodeDescriptor { - static DESCRIPTOR: Lazy = Lazy::new(|| NodeDescriptor { - inputs: Vec::new(), - outputs: Vec::new(), - }); - &DESCRIPTOR - } - fn update( &mut self, _world: &World, _resources: &Resources, render_context: &mut dyn RenderContext, + _input: &ResourceBindings, + _output: &mut ResourceBindings, ) { self.command_queue.execute(render_context); } @@ -104,4 +96,4 @@ impl SystemNode for CameraNode { }, ) } -} +} \ No newline at end of file diff --git a/bevy_render/src/render_graph_2/nodes/mod.rs b/bevy_render/src/render_graph_2/nodes/mod.rs new file mode 100644 index 0000000000..a2559990ff --- /dev/null +++ b/bevy_render/src/render_graph_2/nodes/mod.rs @@ -0,0 +1,9 @@ +mod camera_node; +mod camera2d_node; +mod window_texture_node; +mod window_swapchain_node; + +pub use camera_node::*; +pub use camera2d_node::*; +pub use window_texture_node::*; +pub use window_swapchain_node::*; \ No newline at end of file diff --git a/bevy_render/src/render_graph_2/nodes/window_swapchain_node.rs b/bevy_render/src/render_graph_2/nodes/window_swapchain_node.rs new file mode 100644 index 0000000000..53c5c581bf --- /dev/null +++ b/bevy_render/src/render_graph_2/nodes/window_swapchain_node.rs @@ -0,0 +1,70 @@ +use crate::{ + render_graph_2::{Node, ResourceBindings, ResourceSlot}, + render_resource::{RenderResource, ResourceInfo}, + renderer_2::RenderContext, + texture::TextureDescriptor, +}; +use bevy_app::{EventReader, Events}; +use bevy_window::{WindowCreated, WindowId, WindowResized, Windows}; +use legion::prelude::*; + +pub struct WindowSwapChainNode { + window_id: WindowId, + use_primary_window: bool, + window_resized_event_reader: EventReader, + window_created_event_reader: EventReader, + swap_chain_resource: Option, +} + +impl Node for WindowSwapChainNode { + fn output(&self) -> &[ResourceSlot] { + static OUTPUT: &[ResourceSlot] = &[ResourceSlot::new( + "swapchain_texture", + ResourceInfo::Texture, + )]; + OUTPUT + } + + fn update( + &mut self, + _world: &World, + resources: &Resources, + render_context: &mut dyn RenderContext, + _input: &ResourceBindings, + output: &mut ResourceBindings, + ) { + const WINDOW_TEXTURE: usize = 0; + let window_created_events = resources.get::>().unwrap(); + let window_resized_events = resources.get::>().unwrap(); + let windows = resources.get::().unwrap(); + + let render_resources = render_context.resources_mut(); + let window = if self.use_primary_window { + windows.get_primary().expect("No primary window exists") + } else { + windows + .get(self.window_id) + .expect("Received window resized event for non-existent window") + }; + + // create window swapchain + if let Some(_) = window_created_events + .find_latest(&mut self.window_created_event_reader, |e| { + e.id == window.id + }) + { + render_resources.create_swap_chain(window); + } + + // resize window swapchain + if let Some(_) = window_resized_events + .find_latest(&mut self.window_resized_event_reader, |e| { + e.id == window.id + }) + { + render_resources.create_swap_chain(window); + } + + output.set(WINDOW_TEXTURE, self.swap_chain_resource.unwrap()); + } +} diff --git a/bevy_render/src/render_graph_2/nodes/window_texture_node.rs b/bevy_render/src/render_graph_2/nodes/window_texture_node.rs new file mode 100644 index 0000000000..6ac4eeb973 --- /dev/null +++ b/bevy_render/src/render_graph_2/nodes/window_texture_node.rs @@ -0,0 +1,45 @@ +use crate::{ + render_graph_2::{Node, ResourceBindings, ResourceSlot}, + render_resource::ResourceInfo, + renderer_2::RenderContext, + texture::TextureDescriptor, +}; +use bevy_app::{EventReader, Events}; +use bevy_window::WindowResized; +use legion::prelude::*; + +pub struct WindowTextureNode { + pub descriptor: TextureDescriptor, + window_resized_event_reader: EventReader, +} + +impl Node for WindowTextureNode { + fn output(&self) -> &[ResourceSlot] { + static OUTPUT: &[ResourceSlot] = + &[ResourceSlot::new("window_texture", ResourceInfo::Texture)]; + OUTPUT + } + + fn update( + &mut self, + _world: &World, + resources: &Resources, + render_context: &mut dyn RenderContext, + _input: &ResourceBindings, + output: &mut ResourceBindings, + ) { + const WINDOW_TEXTURE: usize = 0; + let window_resized_events = resources.get::>().unwrap(); + if let Some(event) = window_resized_events.latest(&mut self.window_resized_event_reader) { + let render_resources = render_context.resources_mut(); + if let Some(old_texture) = output.get(WINDOW_TEXTURE) { + render_resources.remove_texture(old_texture); + } + + self.descriptor.size.width = event.width; + self.descriptor.size.height = event.height; + let texture_resource = render_resources.create_texture(&self.descriptor); + output.set(WINDOW_TEXTURE, texture_resource); + } + } +} diff --git a/bevy_render/src/render_resource/resource_providers/camera2d_resource_provider.rs b/bevy_render/src/render_resource/resource_providers/camera2d_resource_provider.rs deleted file mode 100644 index 1c666ae0e3..0000000000 --- a/bevy_render/src/render_resource/resource_providers/camera2d_resource_provider.rs +++ /dev/null @@ -1,91 +0,0 @@ -use bevy_app::{EventReader, Events}; -use bevy_window::WindowResized; - -use crate::{ - camera::{ActiveCamera2d, Camera}, - render_resource::{ - resource_name, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments, - ResourceProvider, - }, - renderer_2::RenderContext, -}; - -use legion::prelude::*; -use zerocopy::AsBytes; - -pub struct Camera2dResourceProvider { - pub camera_buffer: Option, - pub tmp_buffer: Option, - pub window_resized_event_reader: EventReader, -} - -impl Camera2dResourceProvider { - pub fn new(window_resized_event_reader: EventReader) -> Self { - Camera2dResourceProvider { - camera_buffer: None, - tmp_buffer: None, - window_resized_event_reader, - } - } -} - -impl ResourceProvider for Camera2dResourceProvider { - fn initialize( - &mut self, - render_context: &mut dyn RenderContext, - _world: &mut World, - resources: &Resources, - ) { - let buffer = render_context.resources_mut().create_buffer(BufferInfo { - size: std::mem::size_of::<[[f32; 4]; 4]>(), - buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, - ..Default::default() - }); - - let mut render_resource_assignments = - resources.get_mut::().unwrap(); - render_resource_assignments.set(resource_name::uniform::CAMERA2D, buffer); - self.camera_buffer = Some(buffer); - } - - fn update( - &mut self, - render_context: &mut dyn RenderContext, - world: &World, - resources: &Resources, - ) { - let window_resized_events = resources.get::>().unwrap(); - let primary_window_resized_event = window_resized_events - .find_latest(&mut self.window_resized_event_reader, |event| event.is_primary); - - if let Some(_) = primary_window_resized_event { - let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>(); - for (camera, _) in <(Read, Read)>::query().iter(world) { - let camera_matrix: [[f32; 4]; 4] = camera.view_matrix.to_cols_array_2d(); - - if let Some(old_tmp_buffer) = self.tmp_buffer { - render_context.resources_mut().remove_buffer(old_tmp_buffer); - } - - self.tmp_buffer = Some(render_context.resources_mut().create_buffer_mapped( - BufferInfo { - size: matrix_size, - buffer_usage: BufferUsage::COPY_SRC, - ..Default::default() - }, - &mut |data, _renderer| { - data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes()); - }, - )); - - render_context.copy_buffer_to_buffer( - self.tmp_buffer.unwrap(), - 0, - self.camera_buffer.unwrap(), - 0, - matrix_size as u64, - ); - } - } - } -} diff --git a/bevy_render/src/render_resource/resource_providers/frame_texture_resource_provider.rs b/bevy_render/src/render_resource/resource_providers/frame_texture_resource_provider.rs index c8515c9950..36bc89ad0c 100644 --- a/bevy_render/src/render_resource/resource_providers/frame_texture_resource_provider.rs +++ b/bevy_render/src/render_resource/resource_providers/frame_texture_resource_provider.rs @@ -1,11 +1,50 @@ use crate::{ - render_resource::{RenderResourceAssignments, ResourceProvider}, + render_graph_2::{Node, ResourceBindings, ResourceSlot}, + render_resource::{RenderResourceAssignments, ResourceInfo, ResourceProvider}, renderer_2::RenderContext, texture::TextureDescriptor, }; -use bevy_window::Windows; +use bevy_app::{EventReader, Events}; +use bevy_window::{WindowResized, Windows}; use legion::prelude::*; +pub struct WindowTextureNode { + pub name: String, + pub descriptor: TextureDescriptor, + pub window_resized_event_reader: EventReader, +} + +impl Node for WindowTextureNode { + fn output(&self) -> &[ResourceSlot] { + static OUTPUT: &[ResourceSlot] = + &[ResourceSlot::new("window_texture", ResourceInfo::Texture)]; + OUTPUT + } + + fn update( + &mut self, + _world: &World, + resources: &Resources, + render_context: &mut dyn RenderContext, + _input: &ResourceBindings, + output: &mut ResourceBindings, + ) { + const WINDOW_TEXTURE: usize = 0; + let window_resized_events = resources.get::>().unwrap(); + if let Some(event) = window_resized_events.latest(&mut self.window_resized_event_reader) { + let render_resources = render_context.resources_mut(); + if let Some(old_texture) = output.get(WINDOW_TEXTURE) { + render_resources.remove_texture(old_texture); + } + + self.descriptor.size.width = event.width; + self.descriptor.size.height = event.height; + let texture_resource = render_resources.create_texture(&self.descriptor); + output.set(WINDOW_TEXTURE, texture_resource); + } + } +} + pub struct FrameTextureResourceProvider { pub name: String, pub descriptor: TextureDescriptor, diff --git a/bevy_render/src/render_resource/resource_providers/mod.rs b/bevy_render/src/render_resource/resource_providers/mod.rs index aec446a5c0..fbf418c043 100644 --- a/bevy_render/src/render_resource/resource_providers/mod.rs +++ b/bevy_render/src/render_resource/resource_providers/mod.rs @@ -1,12 +1,8 @@ -mod camera2d_resource_provider; -mod camera_resource_provider; mod frame_texture_resource_provider; mod light_resource_provider; mod mesh_resource_provider; mod uniform_resource_provider; -pub use camera2d_resource_provider::*; -pub use camera_resource_provider::*; pub use frame_texture_resource_provider::*; pub use light_resource_provider::*; pub use mesh_resource_provider::*; diff --git a/bevy_transform/benches/local_to_world.rs b/bevy_transform/benches/local_to_world.rs index 77b4402aed..71d9563f63 100644 --- a/bevy_transform/benches/local_to_world.rs +++ b/bevy_transform/benches/local_to_world.rs @@ -1,46 +1,46 @@ -#![feature(test)] +// #![feature(test)] -extern crate test; +// extern crate test; -use legion::prelude::*; -use legion_transform::{local_to_world_system, prelude::*}; -use test::Bencher; +// use legion::prelude::*; +// use bevy_transform::{local_to_world_system, prelude::*}; +// use test::Bencher; -#[bench] -fn local_to_world_update_without_change(b: &mut Bencher) { - let _ = env_logger::builder().is_test(true).try_init(); +// #[bench] +// fn local_to_world_update_without_change(b: &mut Bencher) { +// let _ = env_logger::builder().is_test(true).try_init(); - let mut world = Universe::new().create_world(); - let system = local_to_world_system::build(&mut world); +// let mut world = Universe::new().create_world(); +// let system = local_to_world_system::build(&mut world); - let ltw = LocalToWorld::identity(); - let t = Translation::new(1.0, 2.0, 3.0); - let r = Rotation::from_euler_angles(1.0, 2.0, 3.0); - let s = Scale(2.0); - let nus = NonUniformScale::new(1.0, 2.0, 3.0); +// let ltw = LocalToWorld::identity(); +// let t = Translation::new(1.0, 2.0, 3.0); +// let r = Rotation::from_euler_angles(1.0, 2.0, 3.0); +// let s = Scale(2.0); +// let nus = NonUniformScale::new(1.0, 2.0, 3.0); - // Add N of every combination of transform types. - let n = 1000; - let _translation = *world.insert((), vec![(ltw, t); n]).first().unwrap(); - let _rotation = *world.insert((), vec![(ltw, r); n]).first().unwrap(); - let _scale = *world.insert((), vec![(ltw, s); n]).first().unwrap(); - let _non_uniform_scale = *world.insert((), vec![(ltw, nus); n]).first().unwrap(); - let _translation_and_rotation = *world.insert((), vec![(ltw, t, r); n]).first().unwrap(); - let _translation_and_scale = *world.insert((), vec![(ltw, t, s); n]).first().unwrap(); - let _translation_and_nus = *world.insert((), vec![(ltw, t, nus); n]).first().unwrap(); - let _rotation_scale = *world.insert((), vec![(ltw, r, s); n]).first().unwrap(); - let _rotation_nus = *world.insert((), vec![(ltw, r, nus); n]).first().unwrap(); - let _translation_rotation_scale = *world.insert((), vec![(ltw, t, r, s); n]).first().unwrap(); - let _translation_rotation_nus = *world.insert((), vec![(ltw, t, r, nus); n]).first().unwrap(); +// // Add N of every combination of transform types. +// let n = 1000; +// let _translation = *world.insert((), vec![(ltw, t); n]).first().unwrap(); +// let _rotation = *world.insert((), vec![(ltw, r); n]).first().unwrap(); +// let _scale = *world.insert((), vec![(ltw, s); n]).first().unwrap(); +// let _non_uniform_scale = *world.insert((), vec![(ltw, nus); n]).first().unwrap(); +// let _translation_and_rotation = *world.insert((), vec![(ltw, t, r); n]).first().unwrap(); +// let _translation_and_scale = *world.insert((), vec![(ltw, t, s); n]).first().unwrap(); +// let _translation_and_nus = *world.insert((), vec![(ltw, t, nus); n]).first().unwrap(); +// let _rotation_scale = *world.insert((), vec![(ltw, r, s); n]).first().unwrap(); +// let _rotation_nus = *world.insert((), vec![(ltw, r, nus); n]).first().unwrap(); +// let _translation_rotation_scale = *world.insert((), vec![(ltw, t, r, s); n]).first().unwrap(); +// let _translation_rotation_nus = *world.insert((), vec![(ltw, t, r, nus); n]).first().unwrap(); - // Run the system once outside the test (which should compute everything and it shouldn't be - // touched again). - system.run(&mut world); - system.command_buffer_mut().write(&mut world); +// // Run the system once outside the test (which should compute everything and it shouldn't be +// // touched again). +// system.run(&mut world); +// system.command_buffer_mut().write(&mut world); - // Then time the already-computed updates. - b.iter(|| { - system.run(&mut world); - system.command_buffer_mut().write(&mut world); - }); -} +// // Then time the already-computed updates. +// b.iter(|| { +// system.run(&mut world); +// system.command_buffer_mut().write(&mut world); +// }); +// } diff --git a/bevy_wgpu/src/wgpu_renderer.rs b/bevy_wgpu/src/wgpu_renderer.rs index e78d6beb9d..4d59ae72a7 100644 --- a/bevy_wgpu/src/wgpu_renderer.rs +++ b/bevy_wgpu/src/wgpu_renderer.rs @@ -6,7 +6,7 @@ use bevy_asset::AssetStorage; use bevy_render::{ pipeline::{update_shader_assignments, PipelineCompiler, PipelineDescriptor}, render_graph::RenderGraph, - render_graph_2::RenderGraph2, + render_graph_2::{LinearScheduler, RenderGraph2, RenderGraphScheduler}, render_resource::RenderResourceAssignments, renderer_2::{GlobalRenderResourceContext, RenderContext, RenderResourceContext}, }; @@ -245,10 +245,15 @@ impl WgpuRenderer { .context .downcast_mut::() .unwrap(); + let mut linear_scheduler = LinearScheduler::default(); let mut render_context = WgpuRenderContext::new(self.device.clone(), render_resource_context.clone()); - for node in render_graph.get_schedule() { - node.update(world, resources, &mut render_context); + for mut stage in linear_scheduler.get_stages(&mut render_graph) { + for job in stage.iter_mut() { + for node_state in job.iter_mut() { + node_state.node.update(world, resources, &mut render_context, &node_state.input, &mut node_state.output); + } + } } let command_buffer = render_context.finish();