render: move more render code into system scheduler

This commit is contained in:
Carter Anderson 2020-06-13 18:38:25 -07:00
parent eed40fee9c
commit 5f0363a4f5
6 changed files with 62 additions and 35 deletions

View File

@ -35,17 +35,24 @@ use base_render_graph::{BaseRenderGraphBuilder, BaseRenderGraphConfig};
use bevy_app::{AppBuilder, AppPlugin};
use bevy_asset::AddAsset;
use bevy_type_registry::RegisterType;
use draw::{clear_draw_system, Draw, RenderPipelines};
use draw::{clear_draw_system, draw_system, Draw, RenderPipelines};
use legion::prelude::IntoSystem;
use mesh::mesh_resource_provider_system;
use render_graph::RenderGraph;
use pipeline::compile_pipelines_system;
use render_graph::{system::render_graph_schedule_executor_system, RenderGraph};
use render_resource::render_resource_sets_system;
use std::ops::Range;
use texture::{PngTextureLoader, TextureResourceSystemState};
pub mod stage {
/// Stage where render resources are set up
pub static RENDER_RESOURCE: &str = "render_resource";
pub static PRE_RENDER: &str = "pre_render";
/// Stage where Render Graph systems are run. In general you shouldn't add systems to this stage manually.
pub static RENDER_GRAPH_SYSTEMS: &str = "render_graph_systems";
// Stage where draw systems are executed. This is generally where Draw components are setup
pub static DRAW: &str = "draw";
pub static RENDER: &str = "render";
pub static POST_RENDER: &str = "post_render";
}
pub struct RenderPlugin {
@ -64,8 +71,10 @@ impl Default for RenderPlugin {
impl AppPlugin for RenderPlugin {
fn build(&self, app: &mut AppBuilder) {
app.add_stage_after(bevy_asset::stage::ASSET_EVENTS, stage::RENDER_RESOURCE)
.add_stage_after(stage::RENDER_RESOURCE, stage::PRE_RENDER)
.add_stage_after(stage::PRE_RENDER, stage::RENDER)
.add_stage_after(stage::RENDER_RESOURCE, stage::RENDER_GRAPH_SYSTEMS)
.add_stage_after(stage::RENDER_GRAPH_SYSTEMS, stage::DRAW)
.add_stage_after(stage::DRAW, stage::RENDER)
.add_stage_after(stage::RENDER, stage::POST_RENDER)
.add_asset::<Mesh>()
.add_asset::<Texture>()
.add_asset::<Shader>()
@ -92,11 +101,25 @@ impl AppPlugin for RenderPlugin {
bevy_app::stage::POST_UPDATE,
camera::camera_system::<PerspectiveProjection>,
)
// TODO: turn these "resource systems" into graph nodes and remove the RENDER_RESOURCE stage
.init_system_to_stage(stage::RENDER_RESOURCE, mesh_resource_provider_system)
.add_system_to_stage(
stage::RENDER_RESOURCE,
Texture::texture_resource_system.system(),
);
)
.add_system_to_stage(
stage::RENDER_GRAPH_SYSTEMS,
render_graph_schedule_executor_system,
)
.add_system_to_stage(
stage::RENDER_GRAPH_SYSTEMS,
compile_pipelines_system.system(),
)
.add_system_to_stage(
stage::RENDER_GRAPH_SYSTEMS,
render_resource_sets_system.system(),
)
.add_system_to_stage(stage::DRAW, draw_system::<RenderPipelines>.system());
if let Some(ref config) = self.base_render_graph_config {
let resources = app.resources();

View File

@ -5,6 +5,7 @@ mod node;
mod node_slot;
pub mod nodes;
mod schedule;
pub mod system;
pub use command::*;
pub use edge::*;
pub use graph::*;

View File

@ -0,0 +1,18 @@
use legion::prelude::{Resources, World};
use super::RenderGraph;
pub fn render_graph_schedule_executor_system(world: &mut World, resources: &mut Resources) {
// run render graph systems
let mut system_executor = {
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
render_graph.take_executor()
};
if let Some(executor) = system_executor.as_mut() {
executor.execute(world, resources);
}
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
if let Some(executor) = system_executor.take() {
render_graph.set_executor(executor);
}
}

View File

@ -10,7 +10,10 @@ pub use wgpu_renderer::*;
pub use wgpu_resources::*;
use bevy_app::{AppBuilder, AppPlugin};
use bevy_render::renderer::RenderResources;
use bevy_render::{
render_resource::{free_shared_buffers_system, SharedBuffers},
renderer::RenderResources,
};
use legion::prelude::*;
use renderer::WgpuRenderResourceContext;
@ -20,7 +23,11 @@ pub struct WgpuPlugin;
impl AppPlugin for WgpuPlugin {
fn build(&self, app: &mut AppBuilder) {
let render_system = wgpu_render_system(app.resources_mut());
app.add_system_to_stage(bevy_render::stage::RENDER, render_system);
app.add_system_to_stage(bevy_render::stage::RENDER, render_system)
.add_system_to_stage(
bevy_render::stage::POST_RENDER,
free_shared_buffers_system.system(),
);
}
}
@ -29,6 +36,9 @@ pub fn wgpu_render_system(resources: &mut Resources) -> impl FnMut(&mut World, &
resources.insert(RenderResources::new(WgpuRenderResourceContext::new(
wgpu_renderer.device.clone(),
)));
resources.insert(SharedBuffers::new(Box::new(
WgpuRenderResourceContext::new(wgpu_renderer.device.clone()),
)));
move |world, resources| {
wgpu_renderer.update(world, resources);
}

View File

@ -476,8 +476,8 @@ impl RenderResourceContext for WgpuRenderResourceContext {
.map(|indexed_assignment| {
let wgpu_resource = match &indexed_assignment.assignment {
RenderResourceAssignment::Texture(resource) => {
let texture = texture_views.get(&resource).unwrap();
wgpu::BindingResource::TextureView(texture)
let texture_view = texture_views.get(&resource).expect(&format!("{:?}", resource));
wgpu::BindingResource::TextureView(texture_view)
}
RenderResourceAssignment::Sampler(resource) => {
let sampler = samplers.get(&resource).unwrap();

View File

@ -1,10 +1,7 @@
use crate::renderer::{WgpuRenderGraphExecutor, WgpuRenderResourceContext};
use bevy_app::{EventReader, Events};
use bevy_render::{
draw::{draw_system, RenderPipelines},
pipeline::compile_pipelines_system,
render_graph::{DependentNodeStager, RenderGraph, RenderGraphStager},
render_resource::render_resource_sets_system,
renderer::RenderResources,
};
use bevy_window::{WindowCreated, WindowResized, Windows};
@ -82,29 +79,7 @@ impl WgpuRenderer {
}
pub fn run_graph(&mut self, world: &mut World, resources: &mut Resources) {
// TODO: move this to a thread-local system
// run systems
let mut system_executor = {
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
render_graph.take_executor()
};
if let Some(executor) = system_executor.as_mut() {
executor.execute(world, resources);
}
// TODO: move these to a scheduler
compile_pipelines_system.system().run(world, resources);
render_resource_sets_system.system().run(world, resources);
draw_system::<RenderPipelines>
.system()
.run(world, resources);
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
if let Some(executor) = system_executor.take() {
render_graph.set_executor(executor);
}
// stage nodes
let mut stager = DependentNodeStager::loose_grouping();
let stages = stager.get_stages(&render_graph).unwrap();