Skip to main content

petaplot_render/
context.rs

1use std::sync::Arc;
2use wgpu::{Adapter, Device, Instance, Queue};
3
4/// Contexto principal de GPU administrando la instancia de wgpu, adaptador, dispositivo y cola de comandos.
5pub struct RenderContext {
6    pub instance: Instance,
7    pub adapter: Adapter,
8    pub device: Arc<Device>,
9    pub queue: Arc<Queue>,
10}
11
12impl RenderContext {
13    /// Inicializa el contexto de GPU de forma asíncrona seleccionando el backend nativo por hardware (Vulkan, Metal o D3D12).
14    pub async fn new_async() -> Result<Self, String> {
15        let instance = Instance::new(wgpu::InstanceDescriptor {
16            backends: wgpu::Backends::PRIMARY,
17            ..Default::default()
18        });
19
20        let adapter = instance
21            .request_adapter(&wgpu::RequestAdapterOptions {
22                power_preference: wgpu::PowerPreference::HighPerformance,
23                compatible_surface: None,
24                force_fallback_adapter: false,
25            })
26            .await
27            .ok_or_else(|| "No se encontró un adaptador GPU compatible en el sistema.".to_string())?;
28
29        let (device, queue) = adapter
30            .request_device(
31                &wgpu::DeviceDescriptor {
32                    label: Some("PetaPlot GPU Device"),
33                    required_features: wgpu::Features::empty(),
34                    required_limits: wgpu::Limits::default(),
35                    memory_hints: wgpu::MemoryHints::Performance,
36                },
37                None,
38            )
39            .await
40            .map_err(|e| format!("Error al crear el dispositivo GPU: {}", e))?;
41
42        Ok(Self {
43            instance,
44            adapter,
45            device: Arc::new(device),
46            queue: Arc::new(queue),
47        })
48    }
49
50    /// Inicialización bloqueante (sincrónica) para integraciones directas en hilos principales.
51    pub fn new_blocking() -> Result<Self, String> {
52        pollster::block_on(Self::new_async())
53    }
54}