use tokio::{runtime::Builder, sync::{mpsc}}; use winit::{event::{Event, WindowEvent}, event_loop::{ControlFlow, EventLoop}, window::{Window, WindowBuilder}}; pub struct Gpu { pub surface: wgpu::Surface, pub device: wgpu::Device, pub queue: wgpu::Queue, pub sc_desc: wgpu::SwapChainDescriptor, pub swap_chain: wgpu::SwapChain, pub swapchain_format: wgpu::TextureFormat, pub adapter: wgpu::Adapter, } impl Gpu { pub async fn new(window: &Window) -> Self { let size = window.inner_size(); let swapchain_format = wgpu::TextureFormat::Bgra8UnormSrgb; let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY); let surface = unsafe { instance.create_surface(window) }; let adapter = instance .request_adapter(&wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::default(), compatible_surface: Some(&surface), }) .await .expect("Failed to find an appropiate adapter"); let (device, queue) = adapter .request_device( &wgpu::DeviceDescriptor { label: None, features: wgpu::Features::NON_FILL_POLYGON_MODE, limits: wgpu::Limits::default(), }, None, ) .await .expect("Failed to create device"); let sc_desc = wgpu::SwapChainDescriptor { usage: wgpu::TextureUsage::RENDER_ATTACHMENT, format: swapchain_format, width: size.width, height: size.height, present_mode: wgpu::PresentMode::Immediate, }; let swap_chain = device.create_swap_chain(&surface, &sc_desc); Self { sc_desc, swap_chain, device, surface, queue, swapchain_format, adapter, } } fn clear(&self) { let frame = self.swap_chain .get_current_frame() .expect("Failed to acquire next swap chain texture") .output; let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); { encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: None, color_attachments: &[wgpu::RenderPassColorAttachment { view: &frame.view, resolve_target: None, ops: wgpu::Operations { load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), store: true, }, }], depth_stencil_attachment: None, }); } self.queue.submit(Some(encoder.finish())); } } fn main() { let runtime = Builder::new_multi_thread() .enable_all() .build() .unwrap(); let (event_tx, mut event_rx) = mpsc::unbounded_channel(); let event_loop = EventLoop::new(); let window = WindowBuilder::new().build(&event_loop).unwrap(); runtime.block_on(async { let gpu = Gpu::new(&window).await; runtime.spawn(async move { loop { let event = event_rx.recv().await.unwrap(); println!("{:?} {:?}", event, std::thread::current().id()); gpu.clear(); } }); }); event_loop.run(move |event, _, control_flow| { *control_flow = ControlFlow::Wait; match &event { Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => *control_flow = ControlFlow::Exit, _ => (), } event_tx.send(event.to_static()).unwrap(); }); }