use crate::{GpuInitError, GpuRendererSettings, PowerPreference};
pub struct HeadlessGpu {
pub device: wgpu::Device,
pub queue: wgpu::Queue,
pub adapter_info: String,
}
impl HeadlessGpu {
pub async fn new(settings: GpuRendererSettings) -> Result<Self, GpuInitError> {
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle());
let power_preference = match settings.power_preference {
PowerPreference::Low => wgpu::PowerPreference::LowPower,
PowerPreference::High => wgpu::PowerPreference::HighPerformance,
};
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference,
compatible_surface: None,
force_fallback_adapter: false,
})
.await
.map_err(|_| GpuInitError::NoAdapter)?;
let info = adapter.get_info();
let adapter_info = format!(
"{name} ({backend:?}, {device_type:?})",
name = info.name,
backend = info.backend,
device_type = info.device_type,
);
let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
label: Some("roxlap-gpu headless device"),
required_features: wgpu::Features::empty(),
required_limits: crate::pick_required_limits(&adapter.limits()),
experimental_features: wgpu::ExperimentalFeatures::disabled(),
memory_hints: wgpu::MemoryHints::default(),
trace: wgpu::Trace::Off,
})
.await?;
Ok(Self {
device,
queue,
adapter_info,
})
}
pub fn new_blocking(settings: GpuRendererSettings) -> Result<Self, GpuInitError> {
pollster::block_on(Self::new(settings))
}
}