Skip to main content

zenthra_render/
gpu.rs

1use std::sync::Arc;
2use winit::window::Window;
3
4pub struct GpuContext {
5    pub device: Arc<wgpu::Device>,
6    pub queue: Arc<wgpu::Queue>,
7    pub surface: wgpu::Surface<'static>,
8    pub config: wgpu::SurfaceConfiguration,
9    pub size: winit::dpi::PhysicalSize<u32>,
10    pub scale_factor: f64,
11}
12
13impl GpuContext {
14    pub async fn new(window: Arc<Window>) -> Self {
15        let size = window.inner_size();
16
17        let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
18            backends: wgpu::Backends::all(),
19            flags: wgpu::InstanceFlags::default(),
20            memory_budget_thresholds: Default::default(),
21            backend_options: Default::default(),
22            display: Default::default(),
23        });
24        let surface = instance.create_surface(window.clone()).unwrap();
25
26        let adapter = instance
27            .request_adapter(&wgpu::RequestAdapterOptions {
28                power_preference: wgpu::PowerPreference::HighPerformance,
29                compatible_surface: Some(&surface),
30                force_fallback_adapter: false,
31            })
32            .await
33            .unwrap();
34
35        let (device, queue) = adapter
36            .request_device(&wgpu::DeviceDescriptor {
37                label: Some("Zenthra Device"),
38                required_features: wgpu::Features::empty(),
39                required_limits: wgpu::Limits::default(),
40                memory_hints: Default::default(),
41                trace: wgpu::Trace::Off,
42                experimental_features: wgpu::ExperimentalFeatures::disabled(),
43            })
44            .await
45            .unwrap();
46
47        let surface_caps = surface.get_capabilities(&adapter);
48        let surface_format = surface_caps
49            .formats
50            .iter()
51            .find(|f| f.is_srgb())
52            .copied()
53            .unwrap_or(surface_caps.formats[0]);
54
55        let config = wgpu::SurfaceConfiguration {
56            usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
57            format: surface_format,
58            width: size.width,
59            height: size.height,
60            present_mode: wgpu::PresentMode::AutoVsync,
61            alpha_mode: surface_caps.alpha_modes[0],
62            view_formats: vec![],
63            desired_maximum_frame_latency: 2,
64        };
65        surface.configure(&device, &config);
66
67        let scale_factor = window.scale_factor();
68
69        Self {
70            device: Arc::new(device),
71            queue: Arc::new(queue),
72            surface,
73            config,
74            size,
75            scale_factor,
76        }
77    }
78
79    pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>, scale_factor: f64) {
80        if new_size.width > 0 && new_size.height > 0 {
81            self.size = new_size;
82            self.scale_factor = scale_factor;
83            self.config.width = new_size.width;
84            self.config.height = new_size.height;
85            self.surface.configure(&self.device, &self.config);
86        }
87    }
88}