//! # Context Module //! //! Initializes the GPU, creates the surface, and holds the Device and Queue. It is static (created once at startup). use std::sync::Arc; use wgpu::{Adapter, Device, Instance, Queue, Surface}; use winit::window::Window; use crate::error::WsgError; /// Represents the GPU context. Holds all WGPU objects needed for rendering. /// Created once at startup and shared across frames via Arc. pub struct Context { /// The entry point to wgpu — manages connections with graphics drivers (Vulkan, Metal, DX12). pub instance: Instance, /// Rendering target surface linking wgpu to the window (winit). pub surface: Surface<'static>, /// Physical or software GPU adapter selected by the user. pub adapter: Adapter, /// The engine core — creates buffers, textures, pipelines. pub device: Device, /// Command submission queue — drawing commands are sent here for execution. pub queue: Queue, } impl Context { /// Initializes the WGPU context. Creates the surface from the window, requests a device from the adapter, /// and stores all required objects (instance, surface, adapter, device, queue). /// Called once at application startup. Returns an error if GPU initialization fails. pub async fn new(window: Arc) -> Result { // WGPU instance let instance = wgpu::Instance::default(); // Surface (bound to window lifecycle, so unsafe) let surface = instance .create_surface(window) .map_err(|e| WsgError::SurfaceCreation(e))?; // Request for adapter (GPU) let adapter = instance .request_adapter(&wgpu::RequestAdapterOptions { compatible_surface: Some(&surface), ..Default::default() }) .await .map_err(|_| WsgError::NoAdapter)?; // Request for adapter device and queue let (device, queue) = adapter .request_device(&wgpu::DeviceDescriptor::default()) .await .map_err(|_| WsgError::DeviceCreation)?; Ok(Self { instance, surface, adapter, device, queue, }) } }