arcane_engine/renderer/
gpu.rs1use anyhow::{Context, Result};
2use std::sync::Arc;
3
4pub struct GpuContext {
6 pub device: wgpu::Device,
7 pub queue: wgpu::Queue,
8 pub surface: wgpu::Surface<'static>,
9 pub config: wgpu::SurfaceConfiguration,
10}
11
12impl GpuContext {
13 pub fn new(window: Arc<winit::window::Window>) -> Result<Self> {
15 let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor {
16 backends: wgpu::Backends::all(),
17 ..Default::default()
18 });
19
20 let surface = instance
21 .create_surface(window.clone())
22 .context("Failed to create wgpu surface")?;
23
24 let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions {
25 power_preference: wgpu::PowerPreference::default(),
26 compatible_surface: Some(&surface),
27 force_fallback_adapter: false,
28 }))
29 .context("No suitable GPU adapter found")?;
30
31 let (device, queue) = pollster::block_on(adapter.request_device(
32 &wgpu::DeviceDescriptor {
33 label: Some("arcane_device"),
34 required_features: wgpu::Features::empty(),
35 required_limits: wgpu::Limits::default(),
36 ..Default::default()
37 },
38 None,
39 ))
40 .context("Failed to create GPU device")?;
41
42 let size = window.inner_size();
43 let surface_caps = surface.get_capabilities(&adapter);
44 let surface_format = surface_caps
45 .formats
46 .iter()
47 .find(|f| f.is_srgb())
48 .copied()
49 .unwrap_or(surface_caps.formats[0]);
50
51 let config = wgpu::SurfaceConfiguration {
52 usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
53 format: surface_format,
54 width: size.width.max(1),
55 height: size.height.max(1),
56 present_mode: wgpu::PresentMode::AutoVsync,
57 alpha_mode: surface_caps.alpha_modes[0],
58 view_formats: vec![],
59 desired_maximum_frame_latency: 2,
60 };
61
62 surface.configure(&device, &config);
63
64 Ok(Self {
65 device,
66 queue,
67 surface,
68 config,
69 })
70 }
71}