move swap_chain and device initialization to render_graph

This commit is contained in:
Carter Anderson 2020-01-14 18:57:10 -08:00
parent e1c1da027b
commit 0e72f073e1
4 changed files with 98 additions and 74 deletions

11
CREDITS.md Normal file
View file

@ -0,0 +1,11 @@
# Bevy Credits
## Adapted Code
* legion_transform
* wgpu-rs examples
## Insipration
* amethyst
* coffee

View file

@ -11,7 +11,6 @@ use crate::{render::*, core::Time};
pub struct App { pub struct App {
pub world: World, pub world: World,
pub render_graph: RenderGraph, pub render_graph: RenderGraph,
pub swap_chain: Option<wgpu::SwapChain>,
pub schedule: Schedule, pub schedule: Schedule,
} }
@ -21,7 +20,6 @@ impl App {
world, world,
schedule: schedule, schedule: schedule,
render_graph, render_graph,
swap_chain: None,
} }
} }
@ -30,73 +28,30 @@ impl App {
time.start(); time.start();
} }
self.schedule.execute(&mut self.world); self.schedule.execute(&mut self.world);
self.render(); self.render_graph.render(&mut self.world);
if let Some(mut time) = self.world.resources.get_mut::<Time>() { if let Some(mut time) = self.world.resources.get_mut::<Time>() {
time.stop(); time.stop();
} }
} }
fn resize(&mut self, width: u32, height: u32) {
self.swap_chain = Some(self.render_graph.resize(width, height, &mut self.world));
}
fn handle_event(&mut self, _: WindowEvent) {} fn handle_event(&mut self, _: WindowEvent) {}
fn render(&mut self) {
self.render_graph
.render(&mut self.world, self.swap_chain.as_mut().unwrap());
}
pub fn run(mut self) { pub fn run(mut self) {
env_logger::init(); env_logger::init();
let event_loop = EventLoop::new(); let event_loop = EventLoop::new();
log::info!("Initializing the window..."); log::info!("Initializing the window...");
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
},
wgpu::BackendBit::PRIMARY,
)
.unwrap();
let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
});
let (window, size, surface) = {
let window = winit::window::Window::new(&event_loop).unwrap(); let window = winit::window::Window::new(&event_loop).unwrap();
window.set_title("bevy"); window.set_title("bevy");
window.set_inner_size(winit::dpi::LogicalSize::new(1280, 720)); window.set_inner_size(winit::dpi::LogicalSize::new(1280, 720));
let size = window.inner_size();
let surface = wgpu::Surface::create(&window);
(window, size, surface)
};
let swap_chain_descriptor = wgpu::SwapChainDescriptor { self.world.resources.insert(window);
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::Bgra8UnormSrgb,
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Vsync,
};
let swap_chain = device.create_swap_chain(&surface, &swap_chain_descriptor);
log::info!("Initializing the example..."); log::info!("Initializing the example...");
self.render_graph.initialize( self.render_graph.initialize(
&mut self.world, &mut self.world,
device,
swap_chain_descriptor,
queue,
surface,
); );
self.world.resources.insert(window);
self.swap_chain = Some(swap_chain);
log::info!("Entering render loop..."); log::info!("Entering render loop...");
event_loop.run(move |event, _, control_flow| { event_loop.run(move |event, _, control_flow| {
*control_flow = if cfg!(feature = "metal-auto-capture") { *control_flow = if cfg!(feature = "metal-auto-capture") {
@ -109,7 +64,7 @@ impl App {
event: WindowEvent::Resized(size), event: WindowEvent::Resized(size),
.. ..
} => { } => {
self.resize(size.width, size.height); self.render_graph.resize(size.width, size.height, &mut self.world);
} }
event::Event::WindowEvent { event, .. } => match event { event::Event::WindowEvent { event, .. } => match event {
WindowEvent::KeyboardInput { WindowEvent::KeyboardInput {

View file

@ -1,7 +1,7 @@
use crate::{ use crate::{
asset::*, asset::*,
legion::{ legion::{
prelude::{Schedule, Schedulable, World}, prelude::{Schedule, Schedulable, World, Runnable},
}, },
render::{passes::*, *}, render::{passes::*, *},
legion_transform::transform_system_bundle, ui, app::App, core::Time, legion_transform::transform_system_bundle, ui, app::App, core::Time,
@ -15,6 +15,7 @@ pub struct AppBuilder {
pub world: World, pub world: World,
pub render_graph: RenderGraph, pub render_graph: RenderGraph,
pub system_stages: HashMap<String, Vec<Box<dyn Schedulable>>>, pub system_stages: HashMap<String, Vec<Box<dyn Schedulable>>>,
pub runnable_stages: HashMap<String, Vec<Box<dyn Runnable>>>,
pub stage_order: Vec<String>, pub stage_order: Vec<String>,
} }
@ -24,6 +25,7 @@ impl AppBuilder {
world: World::new(), world: World::new(),
render_graph: RenderGraph::new(), render_graph: RenderGraph::new(),
system_stages: HashMap::new(), system_stages: HashMap::new(),
runnable_stages: HashMap::new(),
stage_order: Vec::new(), stage_order: Vec::new(),
} }
} }
@ -38,6 +40,14 @@ impl AppBuilder {
schedule_builder = schedule_builder.flush(); schedule_builder = schedule_builder.flush();
} }
if let Some((_name, stage_runnables)) = self.runnable_stages.remove_entry(stage_name) {
for system in stage_runnables {
schedule_builder = schedule_builder.add_thread_local(system);
}
schedule_builder = schedule_builder.flush();
}
} }
App::new(self.world, schedule_builder.build(), self.render_graph) App::new(self.world, schedule_builder.build(), self.render_graph)
@ -73,6 +83,18 @@ impl AppBuilder {
self self
} }
pub fn add_runnable_to_stage(mut self, stage_name: &str, system: Box<dyn Runnable>) -> Self {
if let None = self.runnable_stages.get(stage_name) {
self.runnable_stages.insert(stage_name.to_string(), Vec::new());
self.stage_order.push(stage_name.to_string());
}
let stages = self.runnable_stages.get_mut(stage_name).unwrap();
stages.push(system);
self
}
pub fn add_default_passes(mut self) -> Self { pub fn add_default_passes(mut self) -> Self {
let msaa_samples = 4; let msaa_samples = 4;
let render_graph = &mut self.render_graph; let render_graph = &mut self.render_graph;

View file

@ -8,7 +8,7 @@ pub use render_resource_manager::RenderResourceManager;
use crate::render::UniformBuffer; use crate::render::UniformBuffer;
use legion::world::World; use legion::world::World;
use std::collections::HashMap; use std::{collections::HashMap, ops::Deref};
pub struct RenderGraph { pub struct RenderGraph {
pub data: Option<RenderGraphData>, pub data: Option<RenderGraphData>,
@ -16,6 +16,7 @@ pub struct RenderGraph {
pipelines: HashMap<String, Box<dyn Pipeline>>, pipelines: HashMap<String, Box<dyn Pipeline>>,
pass_pipelines: HashMap<String, Vec<String>>, pass_pipelines: HashMap<String, Vec<String>>,
render_resource_managers: Vec<Box<dyn RenderResourceManager>>, render_resource_managers: Vec<Box<dyn RenderResourceManager>>,
swap_chain: Option<wgpu::SwapChain>,
} }
pub struct RenderGraphData { pub struct RenderGraphData {
@ -90,35 +91,70 @@ impl RenderGraph {
pass_pipelines: HashMap::new(), pass_pipelines: HashMap::new(),
render_resource_managers: Vec::new(), render_resource_managers: Vec::new(),
data: None, data: None,
swap_chain: None,
} }
} }
pub fn initialize( pub fn initialize(&mut self, world: &mut World) {
&mut self, let adapter = wgpu::Adapter::request(
world: &mut World, &wgpu::RequestAdapterOptions {
device: wgpu::Device, power_preference: wgpu::PowerPreference::Default,
swap_chain_descriptor: wgpu::SwapChainDescriptor, },
queue: wgpu::Queue, wgpu::BackendBit::PRIMARY,
surface: wgpu::Surface, )
) { .unwrap();
let mut data = RenderGraphData::new(device, swap_chain_descriptor, queue, surface);
let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
});
let (surface, window_size) = {
let window = world.resources.get::<winit::window::Window>().unwrap();
let surface = wgpu::Surface::create(window.deref());
let window_size = window.inner_size();
(surface, window_size)
};
let swap_chain_descriptor = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::Bgra8UnormSrgb,
width: window_size.width,
height: window_size.height,
present_mode: wgpu::PresentMode::Vsync,
};
self.swap_chain = Some(device.create_swap_chain(&surface, &swap_chain_descriptor));
self.data = Some(RenderGraphData::new(
device,
swap_chain_descriptor,
queue,
surface,
));
let data = self.data.as_mut().unwrap();
for render_resource_manager in self.render_resource_managers.iter_mut() { for render_resource_manager in self.render_resource_managers.iter_mut() {
render_resource_manager.initialize(&mut data, world); render_resource_manager.initialize(data, world);
} }
for pass in self.passes.values_mut() { for pass in self.passes.values_mut() {
pass.initialize(&mut data); pass.initialize(data);
} }
for pipeline in self.pipelines.values_mut() { for pipeline in self.pipelines.values_mut() {
pipeline.initialize(&mut data, world); pipeline.initialize(data, world);
} }
self.data = Some(data); self.resize(window_size.width, window_size.height, world);
} }
pub fn render(&mut self, world: &mut World, swap_chain: &mut wgpu::SwapChain) { pub fn render(&mut self, world: &mut World) {
let frame = swap_chain let frame = self.swap_chain
.as_mut()
.unwrap()
.get_next_texture() .get_next_texture()
.expect("Timeout when acquiring next swap chain texture"); .expect("Timeout when acquiring next swap chain texture");
@ -154,13 +190,14 @@ impl RenderGraph {
data.queue.submit(&[command_buffer]); data.queue.submit(&[command_buffer]);
} }
pub fn resize(&mut self, width: u32, height: u32, world: &mut World) -> wgpu::SwapChain { pub fn resize(&mut self, width: u32, height: u32, world: &mut World) {
let data = self.data.as_mut().unwrap(); let data = self.data.as_mut().unwrap();
data.swap_chain_descriptor.width = width; data.swap_chain_descriptor.width = width;
data.swap_chain_descriptor.height = height; data.swap_chain_descriptor.height = height;
let swap_chain = data self.swap_chain = Some(
.device data.device
.create_swap_chain(&data.surface, &data.swap_chain_descriptor); .create_swap_chain(&data.surface, &data.swap_chain_descriptor),
);
let mut encoder = data let mut encoder = data
.device .device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); .create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
@ -180,7 +217,6 @@ impl RenderGraph {
} }
data.queue.submit(&[command_buffer]); data.queue.submit(&[command_buffer]);
swap_chain
} }
pub fn add_render_resource_manager( pub fn add_render_resource_manager(