use crate::fault::FaultSink;
use crate::gpu::GpuContext;
const REQUIRE_GPU: &str = "HENAD_REQUIRE_GPU";
pub fn gpu_required() -> bool {
std::env::var_os(REQUIRE_GPU).is_some_and(|v| !v.is_empty() && v != "0")
}
pub fn headless_context(label: &str, required_features: wgpu::Features) -> Option<GpuContext> {
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle());
let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions::default()));
if let Err(err) = &adapter {
assert!(
!gpu_required(),
"{REQUIRE_GPU} is set but no wgpu adapter is available: {err}"
);
}
let adapter = adapter.ok()?;
if !adapter.features().contains(required_features) {
return None;
}
let device = pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor {
label: Some(label),
required_features,
required_limits: crate::gpu::limits::raise(&adapter, &wgpu::Limits::default(), crate::gpu::GpuNeeds::default()),
..Default::default()
}));
if let Err(err) = &device {
assert!(
!gpu_required(),
"{REQUIRE_GPU} is set but adapter '{}' gave no device: {err}",
adapter.get_info().name
);
}
let (device, queue) = device.ok()?;
Some(GpuContext::new(
device,
queue,
wgpu::TextureFormat::Rgba8Unorm,
FaultSink::new(),
))
}