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 world: World,
pub render_graph: RenderGraph,
pub swap_chain: Option<wgpu::SwapChain>,
pub schedule: Schedule,
}
@ -21,7 +20,6 @@ impl App {
world,
schedule: schedule,
render_graph,
swap_chain: None,
}
}
@ -30,73 +28,30 @@ impl App {
time.start();
}
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>() {
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 render(&mut self) {
self.render_graph
.render(&mut self.world, self.swap_chain.as_mut().unwrap());
}
pub fn run(mut self) {
env_logger::init();
let event_loop = EventLoop::new();
log::info!("Initializing the window...");
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
},
wgpu::BackendBit::PRIMARY,
)
.unwrap();
let window = winit::window::Window::new(&event_loop).unwrap();
window.set_title("bevy");
window.set_inner_size(winit::dpi::LogicalSize::new(1280, 720));
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();
window.set_title("bevy");
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 {
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);
self.world.resources.insert(window);
log::info!("Initializing the example...");
self.render_graph.initialize(
&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...");
event_loop.run(move |event, _, control_flow| {
*control_flow = if cfg!(feature = "metal-auto-capture") {
@ -109,7 +64,7 @@ impl App {
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 {
WindowEvent::KeyboardInput {

View file

@ -1,7 +1,7 @@
use crate::{
asset::*,
legion::{
prelude::{Schedule, Schedulable, World},
prelude::{Schedule, Schedulable, World, Runnable},
},
render::{passes::*, *},
legion_transform::transform_system_bundle, ui, app::App, core::Time,
@ -15,6 +15,7 @@ pub struct AppBuilder {
pub world: World,
pub render_graph: RenderGraph,
pub system_stages: HashMap<String, Vec<Box<dyn Schedulable>>>,
pub runnable_stages: HashMap<String, Vec<Box<dyn Runnable>>>,
pub stage_order: Vec<String>,
}
@ -24,6 +25,7 @@ impl AppBuilder {
world: World::new(),
render_graph: RenderGraph::new(),
system_stages: HashMap::new(),
runnable_stages: HashMap::new(),
stage_order: Vec::new(),
}
}
@ -38,6 +40,14 @@ impl AppBuilder {
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)
@ -73,6 +83,18 @@ impl AppBuilder {
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 {
let msaa_samples = 4;
let render_graph = &mut self.render_graph;

View file

@ -8,7 +8,7 @@ pub use render_resource_manager::RenderResourceManager;
use crate::render::UniformBuffer;
use legion::world::World;
use std::collections::HashMap;
use std::{collections::HashMap, ops::Deref};
pub struct RenderGraph {
pub data: Option<RenderGraphData>,
@ -16,6 +16,7 @@ pub struct RenderGraph {
pipelines: HashMap<String, Box<dyn Pipeline>>,
pass_pipelines: HashMap<String, Vec<String>>,
render_resource_managers: Vec<Box<dyn RenderResourceManager>>,
swap_chain: Option<wgpu::SwapChain>,
}
pub struct RenderGraphData {
@ -90,35 +91,70 @@ impl RenderGraph {
pass_pipelines: HashMap::new(),
render_resource_managers: Vec::new(),
data: None,
swap_chain: None,
}
}
pub fn initialize(
&mut self,
world: &mut World,
device: wgpu::Device,
swap_chain_descriptor: wgpu::SwapChainDescriptor,
queue: wgpu::Queue,
surface: wgpu::Surface,
) {
let mut data = RenderGraphData::new(device, swap_chain_descriptor, queue, surface);
pub fn initialize(&mut self, world: &mut World) {
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 (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() {
render_resource_manager.initialize(&mut data, world);
render_resource_manager.initialize(data, world);
}
for pass in self.passes.values_mut() {
pass.initialize(&mut data);
pass.initialize(data);
}
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) {
let frame = swap_chain
pub fn render(&mut self, world: &mut World) {
let frame = self.swap_chain
.as_mut()
.unwrap()
.get_next_texture()
.expect("Timeout when acquiring next swap chain texture");
@ -154,13 +190,14 @@ impl RenderGraph {
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();
data.swap_chain_descriptor.width = width;
data.swap_chain_descriptor.height = height;
let swap_chain = data
.device
.create_swap_chain(&data.surface, &data.swap_chain_descriptor);
self.swap_chain = Some(
data.device
.create_swap_chain(&data.surface, &data.swap_chain_descriptor),
);
let mut encoder = data
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
@ -180,7 +217,6 @@ impl RenderGraph {
}
data.queue.submit(&[command_buffer]);
swap_chain
}
pub fn add_render_resource_manager(
@ -210,4 +246,4 @@ impl RenderGraph {
pub fn set_pass(&mut self, name: &str, pass: Box<dyn Pass>) {
self.passes.insert(name.to_string(), pass);
}
}
}