Skip to content

Commit

Permalink
defer render systems until render resource context is ready
Browse files Browse the repository at this point in the history
  • Loading branch information
mrk-its committed Oct 14, 2020
1 parent df64e1f commit f53645c
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 24 deletions.
33 changes: 14 additions & 19 deletions crates/bevy_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,19 @@ pub mod prelude {
color::Color,
draw::Draw,
entity::*,
mesh::{shape, Mesh},
mesh::{shape, Mesh, MeshNode},
pass::ClearColor,
pipeline::RenderPipelines,
shader::Shader,
texture::Texture,
};
}

pub mod node {
pub const TEXTURE: &str = "texture";
pub const MESH: &str = "mesh";
}

use crate::prelude::*;
use base::{MainPass, Msaa};
use bevy_app::prelude::*;
Expand All @@ -51,12 +56,10 @@ use std::ops::Range;
use texture::HdrTextureLoader;
#[cfg(feature = "png")]
use texture::ImageTextureLoader;
use texture::TextureResourceSystemState;
use texture::TextureNode;

/// The names of "render" App stages
pub mod stage {
/// Stage where render resources are set up
pub static RENDER_RESOURCE: &str = "render_resource";
/// 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
Expand All @@ -67,7 +70,7 @@ pub mod stage {

/// Adds core render types and systems to an App
pub struct RenderPlugin {
/// configures the "base render graph". If this is not `None`, the "base render graph" will be added
/// configures the "base render graph". If this is not `None`, the "base render graph" will be added
pub base_render_graph_config: Option<BaseRenderGraphConfig>,
}

Expand All @@ -94,8 +97,7 @@ impl Plugin for RenderPlugin {
app.resources_mut().insert(ClearColor::default());
}

app.add_stage_after(bevy_asset::stage::ASSET_EVENTS, stage::RENDER_RESOURCE)
.add_stage_after(stage::RENDER_RESOURCE, stage::RENDER_GRAPH_SYSTEMS)
app.add_stage_after(bevy_asset::stage::ASSET_EVENTS, 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)
Expand All @@ -121,7 +123,6 @@ impl Plugin for RenderPlugin {
.init_resource::<PipelineCompiler>()
.init_resource::<RenderResourceBindings>()
.init_resource::<VertexBufferDescriptors>()
.init_resource::<TextureResourceSystemState>()
.init_resource::<AssetRenderResourceBindings>()
.init_resource::<ActiveCameras>()
.add_system_to_stage(
Expand All @@ -145,15 +146,6 @@ impl Plugin for RenderPlugin {
bevy_app::stage::POST_UPDATE,
camera::visible_entities_system.system(),
)
// TODO: turn these "resource systems" into graph nodes and remove the RENDER_RESOURCE stage
.add_system_to_stage(
stage::RENDER_RESOURCE,
mesh::mesh_resource_provider_system.system(),
)
.add_system_to_stage(
stage::RENDER_RESOURCE,
Texture::texture_resource_system.system(),
)
.add_system_to_stage(
stage::RENDER_GRAPH_SYSTEMS,
render_graph::render_graph_schedule_executor_system.thread_local_system(),
Expand All @@ -168,9 +160,12 @@ impl Plugin for RenderPlugin {
app.init_resource::<Msaa>();
}

let resources = app.resources();
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
render_graph.add_system_node(node::TEXTURE, TextureNode::default());
render_graph.add_system_node(node::MESH, MeshNode::default());

if let Some(ref config) = self.base_render_graph_config {
let resources = app.resources();
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
let msaa = resources.get::<Msaa>().unwrap();
render_graph.add_base_graph(config, &msaa);
let mut active_cameras = resources.get_mut::<ActiveCameras>().unwrap();
Expand Down
30 changes: 29 additions & 1 deletion crates/bevy_render/src/mesh/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@ use crate::{
AsVertexBufferDescriptor, PrimitiveTopology, RenderPipelines, VertexBufferDescriptor,
VertexBufferDescriptors, VertexFormat,
},
render_graph::{CommandQueue, Node, SystemNode},
renderer::{BufferInfo, BufferUsage, RenderResourceContext, RenderResourceId},
};
use bevy_app::prelude::{EventReader, Events};
use bevy_asset::{AssetEvent, Assets, Handle};
use bevy_core::AsBytes;
use bevy_ecs::{Local, Query, Res, ResMut};
use bevy_ecs::{IntoQuerySystem, Local, Query, Res, ResMut};
use bevy_math::*;
use bevy_utils::HashSet;
use std::borrow::Cow;
use thiserror::Error;

pub const VERTEX_BUFFER_ASSET_INDEX: usize = 0;
pub const INDEX_BUFFER_ASSET_INDEX: usize = 1;

#[derive(Clone, Debug)]
pub enum VertexAttributeValues {
Float(Vec<f32>),
Expand Down Expand Up @@ -600,6 +602,32 @@ pub fn mesh_resource_provider_system(
}
}

#[derive(Default)]
pub struct MeshNode {
command_queue: CommandQueue,
}

impl Node for MeshNode {
fn update(
&mut self,
_world: &bevy_ecs::World,
_resources: &bevy_ecs::Resources,
render_context: &mut dyn crate::renderer::RenderContext,
_input: &crate::render_graph::ResourceSlots,
_output: &mut crate::render_graph::ResourceSlots,
) {
self.command_queue.execute(render_context);
}
}

impl SystemNode for MeshNode {
fn get_system(&self, commands: &mut bevy_ecs::Commands) -> Box<dyn bevy_ecs::System> {
let system = mesh_resource_provider_system.system();
commands.insert_local_resource(system.id(), MeshResourceProviderState::default());
system
}
}

#[cfg(test)]
mod tests {
use super::{AsVertexBufferDescriptor, Mesh, VertexAttribute};
Expand Down
6 changes: 5 additions & 1 deletion crates/bevy_render/src/pipeline/render_pipelines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
draw::{Draw, DrawContext},
mesh::{Indices, Mesh},
prelude::Msaa,
renderer::RenderResourceBindings,
renderer::{RenderResourceBindings, RenderResourceContext},
};
use bevy_asset::{Assets, Handle};
use bevy_ecs::{Query, Res, ResMut};
Expand Down Expand Up @@ -73,12 +73,16 @@ impl Default for RenderPipelines {
}

pub fn draw_render_pipelines_system(
render_resource_context: Res<Box<dyn RenderResourceContext>>,
mut draw_context: DrawContext,
mut render_resource_bindings: ResMut<RenderResourceBindings>,
msaa: Res<Msaa>,
meshes: Res<Assets<Mesh>>,
mut query: Query<(&mut Draw, &mut RenderPipelines, &Handle<Mesh>)>,
) {
if !render_resource_context.is_ready() {
return;
}
for (mut draw, mut render_pipelines, mesh_handle) in &mut query.iter() {
if !draw.is_visible {
continue;
Expand Down
8 changes: 8 additions & 0 deletions crates/bevy_render/src/render_graph/system.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
use super::RenderGraph;
use crate::renderer::RenderResourceContext;
use bevy_ecs::{Resources, World};

pub fn render_graph_schedule_executor_system(world: &mut World, resources: &mut Resources) {
if !resources
.get::<Box<dyn RenderResourceContext>>()
.unwrap()
.is_ready()
{
return;
}
// run render graph systems
let (mut system_schedule, commands) = {
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ impl HeadlessRenderResourceContext {
}

impl RenderResourceContext for HeadlessRenderResourceContext {
fn is_ready(&self) -> bool {
true
}

fn create_swap_chain(&self, _window: &Window) {}

fn next_swap_chain_texture(&self, _window: &Window) -> TextureId {
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_render/src/renderer/render_resource_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use downcast_rs::{impl_downcast, Downcast};
use std::ops::Range;

pub trait RenderResourceContext: Downcast + Send + Sync + 'static {
fn is_ready(&self) -> bool;
fn create_swap_chain(&self, window: &Window);
fn next_swap_chain_texture(&self, window: &Window) -> TextureId;
fn drop_swap_chain_texture(&self, resource: TextureId);
Expand Down
32 changes: 29 additions & 3 deletions crates/bevy_render/src/texture/texture.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use super::{SamplerDescriptor, TextureDescriptor, TextureFormat};
use crate::renderer::{
RenderResource, RenderResourceContext, RenderResourceId, RenderResourceType,
use crate::{
render_graph::{CommandQueue, Node, SystemNode},
renderer::{RenderResource, RenderResourceContext, RenderResourceId, RenderResourceType},
};
use bevy_app::prelude::{EventReader, Events};
use bevy_asset::{AssetEvent, Assets, Handle};
use bevy_ecs::{Res, ResMut};
use bevy_ecs::{IntoQuerySystem, Res, ResMut};
use bevy_math::Vec2;
use bevy_utils::HashSet;

Expand Down Expand Up @@ -174,3 +175,28 @@ impl RenderResource for Handle<Texture> {
Some(*self)
}
}

#[derive(Default)]
pub struct TextureNode {
command_queue: CommandQueue,
}

impl Node for TextureNode {
fn update(
&mut self,
_world: &bevy_ecs::World,
_resources: &bevy_ecs::Resources,
render_context: &mut dyn crate::renderer::RenderContext,
_input: &crate::render_graph::ResourceSlots,
_output: &mut crate::render_graph::ResourceSlots,
) {
self.command_queue.execute(render_context);
}
}

impl SystemNode for TextureNode {
fn get_system(&self, commands: &mut bevy_ecs::Commands) -> Box<dyn bevy_ecs::System> {
commands.insert_resource(TextureResourceSystemState::default());
Texture::texture_resource_system.system()
}
}
4 changes: 4 additions & 0 deletions crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ impl WgpuRenderResourceContext {
}

impl RenderResourceContext for WgpuRenderResourceContext {
fn is_ready(&self) -> bool {
true
}

fn create_sampler(&self, sampler_descriptor: &SamplerDescriptor) -> SamplerId {
let mut samplers = self.resources.samplers.write();

Expand Down

0 comments on commit f53645c

Please sign in to comment.