From 831e7fa3ad35132b42322946b093c6bd7628fae1 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 15 Dec 2023 12:23:47 +0100 Subject: [PATCH] Panic early in `Instance::new()` if no backend is enabled Co-Authored-By: Andreas Reich <1220815+Wumpf@users.noreply.github.com> --- wgpu/src/lib.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 48371386f4..b3c665c3f3 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -1786,19 +1786,62 @@ impl Default for Instance { /// Creates a new instance of wgpu with default options. /// /// Backends are set to `Backends::all()`, and FXC is chosen as the `dx12_shader_compiler`. + /// + /// # Panics + /// + /// If no backend feature for the active target platform is enabled, + /// this method will panic, see [`Instance::any_backend_feature_enabled()`]. fn default() -> Self { Self::new(InstanceDescriptor::default()) } } impl Instance { + /// Returns `true` if any backend feature is enabled for the current build configuration. + /// + /// Which feature makes this method return true depends on the target platform: + /// * MacOS/iOS: `metal`, `vulkan-portability` or `angle` + /// * All other: Always returns true + /// + /// TODO: Right now it's otherwise not possible yet to opt-out of all features on most platforms. + /// See + /// * Windows: always enables Vulkan and GLES with no way to opt out + /// * Linux: always enables Vulkan and GLES with no way to opt out + /// * Web: either targets WebGPU backend or, if `webgl` enabled, WebGL + /// * TODO: Support both WebGPU and WebGL at the same time, see + pub const fn any_backend_feature_enabled() -> bool { + // Method intentionally kept verbose to keep it a bit easier to follow! + + // On macOS and iOS, at least one of Metal, Vulkan or GLES backend must be enabled. + let is_mac_or_ios = cfg!(target_os = "macos") || cfg!(target_os = "ios"); + if is_mac_or_ios { + cfg!(feature = "metal") + || cfg!(feature = "vulkan-portability") + || cfg!(feature = "angle") + } else { + true + } + } + /// Create an new instance of wgpu. /// /// # Arguments /// /// - `instance_desc` - Has fields for which [backends][Backends] wgpu will choose /// during instantiation, and which [DX12 shader compiler][Dx12Compiler] wgpu will use. + /// + /// # Panics + /// + /// If no backend feature for the active target platform is enabled, + /// this method will panic, see [`Instance::any_backend_feature_enabled()`]. pub fn new(instance_desc: InstanceDescriptor) -> Self { + if !Self::any_backend_feature_enabled() { + panic!( + "No wgpu backend feature that is implemented for the target platform was enabled. \ + See `wgpu::Instance::any_backend_feature_enabled()` for more information." + ); + } + Self { context: Arc::from(crate::backend::Context::init(instance_desc)), }