rust_animation/
wgpu_context.rs1use wgpu;
6
7pub struct WgpuContext {
9 pub device: wgpu::Device,
10 pub queue: wgpu::Queue,
11 pub surface: Option<wgpu::Surface<'static>>,
12 pub surface_config: Option<wgpu::SurfaceConfiguration>,
13}
14
15impl WgpuContext {
16 pub async fn new_offscreen() -> Self {
18 let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
22 backends: wgpu::Backends::PRIMARY,
23 ..Default::default()
24 });
25 let adapter = instance
26 .request_adapter(&wgpu::RequestAdapterOptions {
27 power_preference: wgpu::PowerPreference::default(),
28 compatible_surface: None,
29 force_fallback_adapter: false,
30 })
31 .await
32 .expect("Failed to find an appropriate adapter");
33
34 let (device, queue) = adapter
35 .request_device(
36 &wgpu::DeviceDescriptor {
37 label: Some("Device"),
38 required_features: wgpu::Features::empty(),
39 required_limits: wgpu::Limits::default(),
40 memory_hints: wgpu::MemoryHints::default(),
41 },
42 None,
43 )
44 .await
45 .expect("Failed to create device");
46
47 WgpuContext {
48 device,
49 queue,
50 surface: None,
51 surface_config: None,
52 }
53 }
54
55 pub async fn new_with_surface(
57 window: impl Into<wgpu::SurfaceTarget<'static>>,
58 width: u32,
59 height: u32,
60 ) -> Self {
61 let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
62 backends: wgpu::Backends::PRIMARY,
63 ..Default::default()
64 });
65
66 let surface = instance
67 .create_surface(window)
68 .expect("Failed to create surface");
69
70 let adapter = instance
71 .request_adapter(&wgpu::RequestAdapterOptions {
72 power_preference: wgpu::PowerPreference::default(),
73 compatible_surface: Some(&surface),
74 force_fallback_adapter: false,
75 })
76 .await
77 .expect("Failed to find an appropriate adapter");
78
79 let (device, queue) = adapter
80 .request_device(
81 &wgpu::DeviceDescriptor {
82 label: Some("Device"),
83 required_features: wgpu::Features::empty(),
84 required_limits: wgpu::Limits::default(),
85 memory_hints: wgpu::MemoryHints::default(),
86 },
87 None,
88 )
89 .await
90 .expect("Failed to create device");
91
92 let surface_caps = surface.get_capabilities(&adapter);
93 let surface_format = surface_caps
94 .formats
95 .iter()
96 .find(|f| f.is_srgb())
97 .copied()
98 .unwrap_or(surface_caps.formats[0]);
99
100 let config = wgpu::SurfaceConfiguration {
101 usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
102 format: surface_format,
103 width,
104 height,
105 present_mode: wgpu::PresentMode::Fifo,
106 alpha_mode: surface_caps.alpha_modes[0],
107 view_formats: vec![],
108 desired_maximum_frame_latency: 2,
109 };
110
111 surface.configure(&device, &config);
112
113 WgpuContext {
114 device,
115 queue,
116 surface: Some(surface),
117 surface_config: Some(config),
118 }
119 }
120
121 pub fn resize(&mut self, width: u32, height: u32) {
123 if let (Some(surface), Some(config)) = (&self.surface, &mut self.surface_config) {
124 config.width = width;
125 config.height = height;
126 surface.configure(&self.device, config);
127 }
128 }
129}