bevy/crates/bevy_wgpu/src/wgpu_renderer.rs

135 lines
4.7 KiB
Rust
Raw Normal View History

use crate::renderer::{
render_resource_sets_system, WgpuRenderGraphExecutor, WgpuRenderResourceContext,
2020-04-12 07:05:47 +00:00
};
2020-04-06 03:19:02 +00:00
use bevy_app::{EventReader, Events};
use bevy_render::{
2020-04-24 04:41:13 +00:00
pipeline::update_shader_assignments,
render_graph::{DependentNodeStager, RenderGraph, RenderGraphStager},
renderer::RenderResources,
2020-01-20 08:57:54 +00:00
};
use bevy_window::{WindowCreated, WindowResized, Windows};
2020-04-06 03:19:02 +00:00
use legion::prelude::*;
2020-04-21 18:43:35 +00:00
use std::{ops::Deref, sync::Arc};
2020-03-03 01:53:39 +00:00
pub struct WgpuRenderer {
2020-05-04 20:11:51 +00:00
pub instance: wgpu::Instance,
pub device: Arc<wgpu::Device>,
2020-03-03 01:53:39 +00:00
pub queue: wgpu::Queue,
pub window_resized_event_reader: EventReader<WindowResized>,
pub window_created_event_reader: EventReader<WindowCreated>,
pub intialized: bool,
2020-03-03 01:53:39 +00:00
}
2020-01-20 08:57:54 +00:00
impl WgpuRenderer {
pub async fn new(
window_resized_event_reader: EventReader<WindowResized>,
window_created_event_reader: EventReader<WindowCreated>,
) -> Self {
2020-05-04 20:11:51 +00:00
let instance = wgpu::Instance::new();
let adapter = instance
.request_adapter(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: None,
},
2020-06-09 17:57:18 +00:00
wgpu::UnsafeExtensions::disallow(),
2020-05-04 20:11:51 +00:00
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();
2020-01-20 08:57:54 +00:00
let (device, queue) = adapter
2020-05-04 20:11:51 +00:00
.request_device(
&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions::empty(),
2020-05-04 20:11:51 +00:00
limits: wgpu::Limits::default(),
2020-06-09 17:57:18 +00:00
shader_validation: true,
},
2020-05-04 20:11:51 +00:00
None,
)
.await
.unwrap();
let device = Arc::new(device);
2020-01-20 08:57:54 +00:00
WgpuRenderer {
2020-05-04 20:11:51 +00:00
instance,
device,
2020-01-20 08:57:54 +00:00
queue,
window_resized_event_reader,
window_created_event_reader,
intialized: false,
2020-01-20 08:57:54 +00:00
}
}
pub fn handle_window_created_events(&mut self, resources: &Resources) {
let mut render_resources = resources.get_mut::<RenderResources>().unwrap();
let render_resource_context = render_resources
.context
.downcast_mut::<WgpuRenderResourceContext>()
.unwrap();
let windows = resources.get::<Windows>().unwrap();
let window_created_events = resources.get::<Events<WindowCreated>>().unwrap();
2020-04-29 08:37:54 +00:00
for window_created_event in self
.window_created_event_reader
.iter(&window_created_events)
{
let window = windows
.get(window_created_event.id)
.expect("Received window created event for non-existent window");
2020-04-06 03:19:02 +00:00
#[cfg(feature = "bevy_winit")]
{
2020-04-06 03:19:02 +00:00
let winit_windows = resources.get::<bevy_winit::WinitWindows>().unwrap();
2020-04-21 18:43:35 +00:00
let winit_window = winit_windows.get_window(window.id).unwrap();
2020-05-04 20:11:51 +00:00
let surface = unsafe { self.instance.create_surface(winit_window.deref()) };
render_resource_context.set_window_surface(window.id, surface);
}
}
2020-01-20 08:57:54 +00:00
}
pub fn run_graph(&mut self, world: &mut World, resources: &mut Resources) {
// run systems
2020-04-24 18:08:46 +00:00
let mut system_executor = {
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
render_graph.take_executor()
};
2020-04-24 18:08:46 +00:00
if let Some(executor) = system_executor.as_mut() {
executor.execute(world, resources);
}
2020-04-24 18:08:46 +00:00
update_shader_assignments(world, resources);
2020-04-24 04:41:13 +00:00
render_resource_sets_system().run(world, resources);
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
2020-04-24 18:08:46 +00:00
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();
let mut borrowed = stages.borrow(&mut render_graph);
// execute stages
2020-04-24 18:08:46 +00:00
let graph_executor = WgpuRenderGraphExecutor {
max_thread_count: 2,
};
2020-04-24 18:08:46 +00:00
graph_executor.execute(
2020-04-24 04:41:13 +00:00
world,
resources,
self.device.clone(),
&mut self.queue,
&mut borrowed,
);
}
pub fn update(&mut self, world: &mut World, resources: &mut Resources) {
self.handle_window_created_events(resources);
2020-04-21 18:43:35 +00:00
self.run_graph(world, resources);
let render_resource_context = resources.get::<RenderResources>().unwrap();
2020-04-24 04:41:13 +00:00
render_resource_context
.context
2020-04-21 18:43:35 +00:00
.drop_all_swap_chain_textures();
2020-06-04 03:08:20 +00:00
render_resource_context.context.clear_bind_groups();
2020-01-20 08:57:54 +00:00
}
2020-03-11 04:57:57 +00:00
}