#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct GpuProbe {
pub usable_gpu: bool,
pub force_cpu: bool,
}
impl GpuProbe {
pub fn gpu() -> Self {
Self { usable_gpu: true, force_cpu: false }
}
pub fn cpu_only() -> Self {
Self { usable_gpu: false, force_cpu: false }
}
pub fn from_env(usable_gpu: bool) -> Self {
Self { usable_gpu, force_cpu: std::env::var_os("FACETT_RENDER_CPU").is_some() }
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Backend {
GpuVello,
CpuVello,
}
impl Backend {
pub fn is_gpu(self) -> bool {
matches!(self, Backend::GpuVello)
}
pub fn label(self) -> &'static str {
match self {
Backend::GpuVello => "L0 SDF wgpu (GPU)",
Backend::CpuVello => "vello_cpu (SIMD/threads)",
}
}
}
pub fn decide(probe: GpuProbe) -> Backend {
let want_gpu = probe.usable_gpu && !probe.force_cpu;
if want_gpu && cfg!(feature = "wgpu") {
Backend::GpuVello
} else {
Backend::CpuVello
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cpu_only_probe_always_picks_cpu() {
assert_eq!(decide(GpuProbe::cpu_only()), Backend::CpuVello);
}
#[test]
fn force_cpu_overrides_a_present_gpu() {
let p = GpuProbe { usable_gpu: true, force_cpu: true };
assert_eq!(decide(p), Backend::CpuVello);
}
#[test]
fn gpu_probe_picks_gpu_only_when_feature_on() {
let got = decide(GpuProbe::gpu());
if cfg!(feature = "wgpu") {
assert_eq!(got, Backend::GpuVello);
} else {
assert_eq!(got, Backend::CpuVello);
}
}
}