use std::sync::Arc;
use winit::window::Window;
use wgpu::{
Device,
DeviceDescriptor,
Queue,
Surface,
SurfaceConfiguration,
SurfaceError,
Instance,
InstanceDescriptor,
SurfaceTexture,
RequestAdapterOptions,
PowerPreference,
PresentMode,
TextureUsages,
};
pub struct GraphicsContext {
pub surface: Surface<'static>,
pub device: Device,
pub queue: Queue,
pub config: SurfaceConfiguration,
}
impl GraphicsContext {
pub async fn new(window: Arc<Window>) -> Result<Self, String> {
let instance = Instance::new(&InstanceDescriptor::default());
let surface = instance.create_surface(Arc::clone(&window))
.map_err(|e| format!("Surface creation failed: {}", e))?;
let adapter = instance.request_adapter(&RequestAdapterOptions {
power_preference: PowerPreference::default(),
compatible_surface: Some(&surface),
force_fallback_adapter: false,
})
.await
.map_err(|e| format!("No suitable adapter found: {}", e))?;
let (device, queue) = adapter.request_device(&DeviceDescriptor::default())
.await
.map_err(|e| format!("Device creation failed: {}", e))?;
let size = window.inner_size();
let surface_caps = surface.get_capabilities(&adapter);
let config = SurfaceConfiguration {
usage: TextureUsages::RENDER_ATTACHMENT,
format: surface_caps.formats[0],
width: size.width,
height: size.height,
present_mode: PresentMode::Fifo,
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
Ok(Self { surface, device, queue, config })
}
pub fn get_current_frame(&self) -> Result<SurfaceTexture, SurfaceError> {
self.surface.get_current_texture()
}
pub fn device(&self) -> &Device {
&self.device
}
pub fn queue(&self) -> &Queue {
&self.queue
}
pub fn config(&self) -> &SurfaceConfiguration {
&self.config
}
}