2020-06-10 06:16:48 +00:00
|
|
|
use crate::renderer::{WgpuRenderGraphExecutor, WgpuRenderResourceContext};
|
2020-07-17 01:47:51 +00:00
|
|
|
use bevy_app::prelude::*;
|
2020-07-10 08:37:06 +00:00
|
|
|
use bevy_ecs::{Resources, World};
|
2020-04-06 03:19:02 +00:00
|
|
|
use bevy_render::{
|
2020-04-25 00:46:54 +00:00
|
|
|
render_graph::{DependentNodeStager, RenderGraph, RenderGraphStager},
|
2020-06-14 19:32:06 +00:00
|
|
|
renderer::RenderResourceContext,
|
2020-01-20 08:57:54 +00:00
|
|
|
};
|
2020-04-10 08:39:38 +00:00
|
|
|
use bevy_window::{WindowCreated, WindowResized, Windows};
|
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,
|
2020-04-15 03:17:22 +00:00
|
|
|
pub device: Arc<wgpu::Device>,
|
2020-03-03 01:53:39 +00:00
|
|
|
pub queue: wgpu::Queue,
|
2020-04-01 01:04:54 +00:00
|
|
|
pub window_resized_event_reader: EventReader<WindowResized>,
|
|
|
|
pub window_created_event_reader: EventReader<WindowCreated>,
|
2020-03-23 01:22:35 +00:00
|
|
|
pub intialized: bool,
|
2020-03-03 01:53:39 +00:00
|
|
|
}
|
|
|
|
|
2020-01-20 08:57:54 +00:00
|
|
|
impl WgpuRenderer {
|
2020-06-10 06:16:48 +00:00
|
|
|
pub async fn new() -> Self {
|
2020-07-10 20:47:31 +00:00
|
|
|
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
|
2020-05-04 20:11:51 +00:00
|
|
|
let adapter = instance
|
2020-07-10 20:47:31 +00:00
|
|
|
.request_adapter(&wgpu::RequestAdapterOptions {
|
2020-08-13 01:53:56 +00:00
|
|
|
power_preference: wgpu::PowerPreference::HighPerformance,
|
2020-07-10 20:47:31 +00:00
|
|
|
compatible_surface: None,
|
|
|
|
})
|
2020-05-04 20:11:51 +00:00
|
|
|
.await
|
2020-08-12 06:58:07 +00:00
|
|
|
.expect("Unable to find a GPU! Make sure you have installed required drivers!");
|
2020-01-20 08:57:54 +00:00
|
|
|
|
2020-03-31 02:21:12 +00:00
|
|
|
let (device, queue) = adapter
|
2020-05-04 20:11:51 +00:00
|
|
|
.request_device(
|
|
|
|
&wgpu::DeviceDescriptor {
|
2020-07-10 20:47:31 +00:00
|
|
|
features: wgpu::Features::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-03-31 02:21:12 +00:00
|
|
|
},
|
2020-05-04 20:11:51 +00:00
|
|
|
None,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2020-04-12 01:40:30 +00:00
|
|
|
let device = Arc::new(device);
|
2020-01-20 08:57:54 +00:00
|
|
|
WgpuRenderer {
|
2020-05-04 20:11:51 +00:00
|
|
|
instance,
|
2020-04-15 03:17:22 +00:00
|
|
|
device,
|
2020-01-20 08:57:54 +00:00
|
|
|
queue,
|
2020-06-10 06:16:48 +00:00
|
|
|
window_resized_event_reader: Default::default(),
|
|
|
|
window_created_event_reader: Default::default(),
|
2020-03-23 01:22:35 +00:00
|
|
|
intialized: false,
|
2020-01-20 08:57:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-25 00:46:54 +00:00
|
|
|
pub fn handle_window_created_events(&mut self, resources: &Resources) {
|
2020-06-14 19:32:06 +00:00
|
|
|
let mut render_resource_context = resources
|
|
|
|
.get_mut::<Box<dyn RenderResourceContext>>()
|
|
|
|
.unwrap();
|
|
|
|
let render_resource_context = render_resource_context
|
2020-04-25 00:46:54 +00:00
|
|
|
.downcast_mut::<WgpuRenderResourceContext>()
|
|
|
|
.unwrap();
|
2020-03-31 02:21:12 +00:00
|
|
|
let windows = resources.get::<Windows>().unwrap();
|
2020-04-01 01:04:54 +00:00
|
|
|
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)
|
2020-04-15 03:17:22 +00:00
|
|
|
{
|
2020-03-31 02:21:12 +00:00
|
|
|
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-03-31 02:21:12 +00:00
|
|
|
{
|
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()) };
|
2020-05-05 19:45:37 +00:00
|
|
|
render_resource_context.set_window_surface(window.id, surface);
|
2020-03-28 20:56:29 +00:00
|
|
|
}
|
2020-01-27 05:44:01 +00:00
|
|
|
}
|
2020-01-20 08:57:54 +00:00
|
|
|
}
|
|
|
|
|
2020-04-20 21:29:21 +00:00
|
|
|
pub fn run_graph(&mut self, world: &mut World, resources: &mut Resources) {
|
2020-04-25 00:46:54 +00:00
|
|
|
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
2020-04-24 00:24:41 +00:00
|
|
|
// stage nodes
|
|
|
|
let mut stager = DependentNodeStager::loose_grouping();
|
|
|
|
let stages = stager.get_stages(&render_graph).unwrap();
|
|
|
|
let mut borrowed = stages.borrow(&mut render_graph);
|
2020-04-25 00:46:54 +00:00
|
|
|
|
2020-04-24 00:24:41 +00:00
|
|
|
// execute stages
|
2020-04-24 18:08:46 +00:00
|
|
|
let graph_executor = WgpuRenderGraphExecutor {
|
2020-04-24 00:24:41 +00:00
|
|
|
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,
|
|
|
|
);
|
2020-04-20 21:29:21 +00:00
|
|
|
}
|
|
|
|
|
2020-04-12 21:47:41 +00:00
|
|
|
pub fn update(&mut self, world: &mut World, resources: &mut Resources) {
|
2020-04-25 00:46:54 +00:00
|
|
|
self.handle_window_created_events(resources);
|
2020-04-21 18:43:35 +00:00
|
|
|
self.run_graph(world, resources);
|
2020-04-15 03:17:22 +00:00
|
|
|
|
2020-06-14 19:32:06 +00:00
|
|
|
let render_resource_context = resources.get::<Box<dyn RenderResourceContext>>().unwrap();
|
|
|
|
render_resource_context.drop_all_swap_chain_textures();
|
|
|
|
render_resource_context.clear_bind_groups();
|
2020-01-20 08:57:54 +00:00
|
|
|
}
|
2020-03-11 04:57:57 +00:00
|
|
|
}
|