mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
move swap_chain and device initialization to render_graph
This commit is contained in:
parent
e1c1da027b
commit
0e72f073e1
4 changed files with 98 additions and 74 deletions
11
CREDITS.md
Normal file
11
CREDITS.md
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Bevy Credits
|
||||||
|
|
||||||
|
## Adapted Code
|
||||||
|
|
||||||
|
* legion_transform
|
||||||
|
* wgpu-rs examples
|
||||||
|
|
||||||
|
## Insipration
|
||||||
|
|
||||||
|
* amethyst
|
||||||
|
* coffee
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(
|
||||||
|
|
Loading…
Reference in a new issue