From 3eeef017d583b6a0481f6d0589e55ed60fe9cc02 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Thu, 1 Dec 2022 09:40:17 -0800 Subject: [PATCH] Make `wgpu-core` users responsible for choosing back ends. Before this change, backend selection is done by target dependencies in `wgpu-core/Cargo.toml`, giving `wgpu-core` users no way to override those choices. (Firefox doesn't want the gles back end, for example.) There doesn't seem to be any way to have a crate select backends based on target architecture and OS that users of that crate can still override. The default features can't be selected based on the target, for example. That implies that we should do the selection as late in the dependency DAG as feasible. Having `wgpu` (and `wgpu-core`'s other dependents) choose backends seems good enough. --- Cargo.lock | 7 --- wgpu-core/Cargo.toml | 22 ++++---- wgpu-core/build.rs | 22 -------- wgpu-core/src/device/mod.rs | 10 ++-- wgpu-core/src/hub.rs | 60 ++++++++++----------- wgpu-core/src/instance.rs | 102 ++++++++++++++++++------------------ wgpu-core/src/lib.rs | 17 ++---- wgpu-hal/Cargo.toml | 2 +- wgpu/Cargo.toml | 33 ++++++++++-- 9 files changed, 130 insertions(+), 145 deletions(-) delete mode 100644 wgpu-core/build.rs diff --git a/Cargo.lock b/Cargo.lock index 021fdf6d781..e371d9c8a73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,12 +259,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "cgl" version = "0.3.2" @@ -2818,7 +2812,6 @@ dependencies = [ "arrayvec 0.7.2", "bit-vec", "bitflags", - "cfg_aliases", "codespan-reporting", "fxhash", "log", diff --git a/wgpu-core/Cargo.toml b/wgpu-core/Cargo.toml index c92865b73d2..8cb44c7dac8 100644 --- a/wgpu-core/Cargo.toml +++ b/wgpu-core/Cargo.toml @@ -17,6 +17,14 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = [] + +# Backends, passed through to wgpu-hal +metal = ["hal/metal"] +vulkan = ["hal/vulkan"] +gles = ["hal/gles"] +dx11 = ["hal/dx11"] +dx12 = ["hal/dx12"] + # Apply run-time checks, even in release builds. These are in addition # to the validation carried out at public APIs in all builds. strict_asserts = [] @@ -60,21 +68,11 @@ workspace = true [target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] web-sys = { workspace = true, features = ["HtmlCanvasElement", "OffscreenCanvas"] } -[target.'cfg(target_arch = "wasm32")'.dependencies] -hal = { workspace = true, features = ["gles"] } - -[target.'cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))'.dependencies] -hal = { workspace = true, features = ["metal"] } -#Note: could also enable "vulkan" for Vulkan Portability - [target.'cfg(all(not(target_arch = "wasm32"), unix, not(target_os = "ios"), not(target_os = "macos")))'.dependencies] -hal = { workspace = true, features = ["vulkan", "gles", "renderdoc"] } +hal = { workspace = true, features = ["renderdoc"] } [target.'cfg(all(not(target_arch = "wasm32"), windows))'.dependencies] -hal = { workspace = true, features = ["vulkan", "dx12", "dx11", "renderdoc"] } +hal = { workspace = true, features = ["renderdoc"] } [target.'cfg(target_os = "emscripten")'.dependencies] hal = { workspace = true, features = ["emscripten"] } - -[build-dependencies] -cfg_aliases.workspace = true diff --git a/wgpu-core/build.rs b/wgpu-core/build.rs deleted file mode 100644 index 445ea245d26..00000000000 --- a/wgpu-core/build.rs +++ /dev/null @@ -1,22 +0,0 @@ -fn main() { - // Setup cfg aliases - cfg_aliases::cfg_aliases! { - // Vendors/systems - wasm: { target_arch = "wasm32" }, - apple: { any(target_os = "ios", target_os = "macos") }, - unix_wo_apple: {all(unix, not(apple))}, - - // Backends - vulkan: { all(not(wasm), any(windows, unix_wo_apple, feature = "vulkan-portability")) }, - metal: { all(not(wasm), apple) }, - dx12: { all(not(wasm), windows) }, - dx11: { all(not(wasm), windows) }, - gl: { - any( - unix_wo_apple, - feature = "angle", - wasm - ) - }, - } -} diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 86c79a9a6d2..ef3d8ee8af7 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -5407,27 +5407,27 @@ impl Global { let mut closures = UserClosures::default(); let mut all_queue_empty = true; - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] { all_queue_empty = self.poll_devices::(force_wait, &mut closures)? && all_queue_empty; } - #[cfg(metal)] + #[cfg(feature = "metal")] { all_queue_empty = self.poll_devices::(force_wait, &mut closures)? && all_queue_empty; } - #[cfg(dx12)] + #[cfg(feature = "dx12")] { all_queue_empty = self.poll_devices::(force_wait, &mut closures)? && all_queue_empty; } - #[cfg(dx11)] + #[cfg(feature = "dx11")] { all_queue_empty = self.poll_devices::(force_wait, &mut closures)? && all_queue_empty; } - #[cfg(gl)] + #[cfg(feature = "gles")] { all_queue_empty = self.poll_devices::(force_wait, &mut closures)? && all_queue_empty; diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index f07010477c2..290df3c716a 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -1057,30 +1057,30 @@ impl Hub { } pub struct Hubs { - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] vulkan: Hub, - #[cfg(metal)] + #[cfg(feature = "metal")] metal: Hub, - #[cfg(dx12)] + #[cfg(feature = "dx12")] dx12: Hub, - #[cfg(dx11)] + #[cfg(feature = "dx11")] dx11: Hub, - #[cfg(gl)] + #[cfg(feature = "gles")] gl: Hub, } impl Hubs { fn new(factory: &F) -> Self { Self { - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] vulkan: Hub::new(factory), - #[cfg(metal)] + #[cfg(feature = "metal")] metal: Hub::new(factory), - #[cfg(dx12)] + #[cfg(feature = "dx12")] dx12: Hub::new(factory), - #[cfg(dx11)] + #[cfg(feature = "dx11")] dx11: Hub::new(factory), - #[cfg(gl)] + #[cfg(feature = "gles")] gl: Hub::new(factory), } } @@ -1089,15 +1089,15 @@ impl Hubs { #[derive(Debug)] pub struct GlobalReport { pub surfaces: StorageReport, - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] pub vulkan: Option, - #[cfg(metal)] + #[cfg(feature = "metal")] pub metal: Option, - #[cfg(dx12)] + #[cfg(feature = "dx12")] pub dx12: Option, - #[cfg(dx11)] + #[cfg(feature = "dx11")] pub dx11: Option, - #[cfg(gl)] + #[cfg(feature = "gles")] pub gl: Option, } @@ -1162,31 +1162,31 @@ impl Global { pub fn generate_report(&self) -> GlobalReport { GlobalReport { surfaces: self.surfaces.data.read().generate_report(), - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] vulkan: if self.instance.vulkan.is_some() { Some(self.hubs.vulkan.generate_report()) } else { None }, - #[cfg(metal)] + #[cfg(feature = "metal")] metal: if self.instance.metal.is_some() { Some(self.hubs.metal.generate_report()) } else { None }, - #[cfg(dx12)] + #[cfg(feature = "dx12")] dx12: if self.instance.dx12.is_some() { Some(self.hubs.dx12.generate_report()) } else { None }, - #[cfg(dx11)] + #[cfg(feature = "dx11")] dx11: if self.instance.dx11.is_some() { Some(self.hubs.dx11.generate_report()) } else { None }, - #[cfg(gl)] + #[cfg(feature = "gles")] gl: if self.instance.gl.is_some() { Some(self.hubs.gl.generate_report()) } else { @@ -1203,23 +1203,23 @@ impl Drop for Global { let mut surface_guard = self.surfaces.data.write(); // destroy hubs before the instance gets dropped - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] { self.hubs.vulkan.clear(&mut surface_guard, true); } - #[cfg(metal)] + #[cfg(feature = "metal")] { self.hubs.metal.clear(&mut surface_guard, true); } - #[cfg(dx12)] + #[cfg(feature = "dx12")] { self.hubs.dx12.clear(&mut surface_guard, true); } - #[cfg(dx11)] + #[cfg(feature = "dx11")] { self.hubs.dx11.clear(&mut surface_guard, true); } - #[cfg(gl)] + #[cfg(feature = "gles")] { self.hubs.gl.clear(&mut surface_guard, true); } @@ -1261,7 +1261,7 @@ impl HalApi for hal::api::Empty { } } -#[cfg(vulkan)] +#[cfg(feature = "vulkan")] impl HalApi for hal::api::Vulkan { const VARIANT: Backend = Backend::Vulkan; fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance { @@ -1285,7 +1285,7 @@ impl HalApi for hal::api::Vulkan { } } -#[cfg(metal)] +#[cfg(feature = "metal")] impl HalApi for hal::api::Metal { const VARIANT: Backend = Backend::Metal; fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance { @@ -1309,7 +1309,7 @@ impl HalApi for hal::api::Metal { } } -#[cfg(dx12)] +#[cfg(feature = "dx12")] impl HalApi for hal::api::Dx12 { const VARIANT: Backend = Backend::Dx12; fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance { @@ -1333,7 +1333,7 @@ impl HalApi for hal::api::Dx12 { } } -#[cfg(dx11)] +#[cfg(feature = "dx11")] impl HalApi for hal::api::Dx11 { const VARIANT: Backend = Backend::Dx11; fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance { @@ -1357,7 +1357,7 @@ impl HalApi for hal::api::Dx11 { } } -#[cfg(gl)] +#[cfg(feature = "gles")] impl HalApi for hal::api::Gles { const VARIANT: Backend = Backend::Gl; fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance { diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 82468881e2f..487abf6fe0e 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -54,15 +54,15 @@ fn downlevel_default_limits_less_than_default_limits() { pub struct Instance { #[allow(dead_code)] pub name: String, - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] pub vulkan: Option>, - #[cfg(metal)] + #[cfg(feature = "metal")] pub metal: Option>, - #[cfg(dx12)] + #[cfg(feature = "dx12")] pub dx12: Option>, - #[cfg(dx11)] + #[cfg(feature = "dx11")] pub dx11: Option>, - #[cfg(gl)] + #[cfg(feature = "gles")] pub gl: Option>, } @@ -87,15 +87,15 @@ impl Instance { Self { name: name.to_string(), - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] vulkan: init(hal::api::Vulkan, backends), - #[cfg(metal)] + #[cfg(feature = "metal")] metal: init(hal::api::Metal, backends), - #[cfg(dx12)] + #[cfg(feature = "dx12")] dx12: init(hal::api::Dx12, backends), - #[cfg(dx11)] + #[cfg(feature = "dx11")] dx11: init(hal::api::Dx11, backends), - #[cfg(gl)] + #[cfg(feature = "gles")] gl: init(hal::api::Gles, backends), } } @@ -112,30 +112,30 @@ impl Instance { } } } - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] destroy(hal::api::Vulkan, &self.vulkan, surface.vulkan); - #[cfg(metal)] + #[cfg(feature = "metal")] destroy(hal::api::Metal, &self.metal, surface.metal); - #[cfg(dx12)] + #[cfg(feature = "dx12")] destroy(hal::api::Dx12, &self.dx12, surface.dx12); - #[cfg(dx11)] + #[cfg(feature = "dx11")] destroy(hal::api::Dx11, &self.dx11, surface.dx11); - #[cfg(gl)] + #[cfg(feature = "gles")] destroy(hal::api::Gles, &self.gl, surface.gl); } } pub struct Surface { pub(crate) presentation: Option, - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] pub vulkan: Option>, - #[cfg(metal)] + #[cfg(feature = "metal")] pub metal: Option>, - #[cfg(dx12)] + #[cfg(feature = "dx12")] pub dx12: Option>, - #[cfg(dx11)] + #[cfg(feature = "dx11")] pub dx11: Option>, - #[cfg(gl)] + #[cfg(feature = "gles")] pub gl: Option>, } @@ -451,15 +451,15 @@ impl Global { let surface = Surface { presentation: None, - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] vulkan: init::(&self.instance.vulkan, display_handle, window_handle), - #[cfg(metal)] + #[cfg(feature = "metal")] metal: init::(&self.instance.metal, display_handle, window_handle), - #[cfg(dx12)] + #[cfg(feature = "dx12")] dx12: init::(&self.instance.dx12, display_handle, window_handle), - #[cfg(dx11)] + #[cfg(feature = "dx11")] dx11: init::(&self.instance.dx11, display_handle, window_handle), - #[cfg(gl)] + #[cfg(feature = "gles")] gl: init::(&self.instance.gl, display_handle, window_handle), }; @@ -468,7 +468,7 @@ impl Global { id.0 } - #[cfg(metal)] + #[cfg(feature = "metal")] pub fn instance_create_surface_metal( &self, layer: *mut std::ffi::c_void, @@ -486,9 +486,9 @@ impl Global { }, //acquired_texture: None, }), - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] vulkan: None, - #[cfg(gl)] + #[cfg(feature = "gles")] gl: None, }; @@ -543,7 +543,7 @@ impl Global { id.0 } - #[cfg(dx12)] + #[cfg(feature = "dx12")] /// # Safety /// /// The visual must be valid and able to be used to make a swapchain with. @@ -556,13 +556,13 @@ impl Global { let surface = Surface { presentation: None, - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] vulkan: None, dx12: self.instance.dx12.as_ref().map(|inst| HalSurface { raw: unsafe { inst.create_surface_from_visual(visual as _) }, }), dx11: None, - #[cfg(gl)] + #[cfg(feature = "gles")] gl: None, }; @@ -615,25 +615,25 @@ impl Global { let mut adapters = Vec::new(); - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] self.enumerate( hal::api::Vulkan, &self.instance.vulkan, &inputs, &mut adapters, ); - #[cfg(metal)] + #[cfg(feature = "metal")] self.enumerate( hal::api::Metal, &self.instance.metal, &inputs, &mut adapters, ); - #[cfg(dx12)] + #[cfg(feature = "dx12")] self.enumerate(hal::api::Dx12, &self.instance.dx12, &inputs, &mut adapters); - #[cfg(dx11)] + #[cfg(feature = "dx11")] self.enumerate(hal::api::Dx11, &self.instance.dx11, &inputs, &mut adapters); - #[cfg(gl)] + #[cfg(feature = "gles")] self.enumerate(hal::api::Gles, &self.instance.gl, &inputs, &mut adapters); adapters @@ -716,7 +716,7 @@ impl Global { .transpose()?; let mut device_types = Vec::new(); - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] let (id_vulkan, adapters_vk) = gather( hal::api::Vulkan, self.instance.vulkan.as_ref(), @@ -725,7 +725,7 @@ impl Global { desc.force_fallback_adapter, &mut device_types, ); - #[cfg(metal)] + #[cfg(feature = "metal")] let (id_metal, adapters_metal) = gather( hal::api::Metal, self.instance.metal.as_ref(), @@ -734,7 +734,7 @@ impl Global { desc.force_fallback_adapter, &mut device_types, ); - #[cfg(dx12)] + #[cfg(feature = "dx12")] let (id_dx12, adapters_dx12) = gather( hal::api::Dx12, self.instance.dx12.as_ref(), @@ -743,7 +743,7 @@ impl Global { desc.force_fallback_adapter, &mut device_types, ); - #[cfg(dx11)] + #[cfg(feature = "dx11")] let (id_dx11, adapters_dx11) = gather( hal::api::Dx11, self.instance.dx11.as_ref(), @@ -752,7 +752,7 @@ impl Global { desc.force_fallback_adapter, &mut device_types, ); - #[cfg(gl)] + #[cfg(feature = "gles")] let (id_gl, adapters_gl) = gather( hal::api::Gles, self.instance.gl.as_ref(), @@ -805,23 +805,23 @@ impl Global { }; let mut selected = preferred_gpu.unwrap_or(0); - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] if let Some(id) = self.select(&mut selected, id_vulkan, adapters_vk) { return Ok(id); } - #[cfg(metal)] + #[cfg(feature = "metal")] if let Some(id) = self.select(&mut selected, id_metal, adapters_metal) { return Ok(id); } - #[cfg(dx12)] + #[cfg(feature = "dx12")] if let Some(id) = self.select(&mut selected, id_dx12, adapters_dx12) { return Ok(id); } - #[cfg(dx11)] + #[cfg(feature = "dx11")] if let Some(id) = self.select(&mut selected, id_dx11, adapters_dx11) { return Ok(id); } - #[cfg(gl)] + #[cfg(feature = "gles")] if let Some(id) = self.select(&mut selected, id_gl, adapters_gl) { return Ok(id); } @@ -845,15 +845,15 @@ impl Global { let fid = A::hub(self).adapters.prepare(input); match A::VARIANT { - #[cfg(vulkan)] + #[cfg(feature = "vulkan")] Backend::Vulkan => fid.assign(Adapter::new(hal_adapter), &mut token).0, - #[cfg(metal)] + #[cfg(feature = "metal")] Backend::Metal => fid.assign(Adapter::new(hal_adapter), &mut token).0, - #[cfg(dx12)] + #[cfg(feature = "dx12")] Backend::Dx12 => fid.assign(Adapter::new(hal_adapter), &mut token).0, - #[cfg(dx11)] + #[cfg(feature = "dx11")] Backend::Dx11 => fid.assign(Adapter::new(hal_adapter), &mut token).0, - #[cfg(gl)] + #[cfg(feature = "gles")] Backend::Gl => fid.assign(Adapter::new(hal_adapter), &mut token).0, _ => unreachable!(), } diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index 9c98aeb867c..c79814dbb7c 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -307,34 +307,27 @@ macro_rules! define_backend_caller { define_backend_caller! { gfx_if_vulkan, gfx_if_vulkan_hidden - if any( - all(not(target_arch = "wasm32"), not(target_os = "ios"), not(target_os = "macos")), - feature = "vulkan-portability" - ) + if feature = "vulkan" } define_backend_caller! { gfx_if_metal, gfx_if_metal_hidden - if all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")) + if feature = "metal" } define_backend_caller! { gfx_if_dx12, gfx_if_dx12_hidden - if all(not(target_arch = "wasm32"), windows) + if feature = "dx12" } define_backend_caller! { gfx_if_dx11, gfx_if_dx11_hidden - if all(not(target_arch = "wasm32"), windows) + if feature = "dx11" } define_backend_caller! { gfx_if_gles, gfx_if_gles_hidden - if any( - all(unix, not(target_os = "macos"), not(target_os = "ios")), - feature = "angle", - target_arch = "wasm32" - ) + if feature = "gles" } /// Dispatch on an [`Id`]'s backend to a backend-generic method. diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index aa8bbcada98..9fee2782c3d 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -27,7 +27,7 @@ rustdoc-args = ["--cfg", "docsrs"] [lib] [features] -default = ["gles"] +default = [] metal = ["naga/msl-out", "block", "foreign-types"] vulkan = ["naga/spv-out", "ash", "gpu-alloc", "gpu-descriptor", "libloading", "smallvec"] gles = ["naga/glsl-out", "glow", "egl", "libloading"] diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 36272c0fda8..fa1a81e4abd 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -88,18 +88,41 @@ emscripten = ["webgl"] vulkan-portability = ["wgc/vulkan-portability"] expose-ids = [] -[target.'cfg(not(target_arch = "wasm32"))'.dependencies.wgc] +# wgpu-core is always available as an optional dependency, "wgc". +# Whenever wgpu-core is selected, we want the GLES backend and raw +# window handle support. +[dependencies.wgc] +optional = true workspace = true -features = ["raw-window-handle"] +features = ["raw-window-handle", "gles"] -[target.'cfg(target_arch = "wasm32")'.dependencies.wgc] +# wgpu-core is required whenever not targeting web APIs directly. +# Whenever wgpu-core is selected, we want the GLES backend and raw +# window handle support. +[target.'cfg(any(not(target_arch = "wasm32"), target_os = "emscripten"))'.dependencies.wgc] workspace = true -features = ["raw-window-handle"] -optional = true +features = ["raw-window-handle", "gles"] + +# We want the wgpu-core Metal backend on macOS and iOS. +# (We should consider also enabling "vulkan" for Vulkan Portability.) +[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgc] +workspace = true +features = ["metal"] + +# We want the wgpu-core Direct3D backends on Windows. +[target.'cfg(windows)'.dependencies.wgc] +workspace = true +features = ["dx11", "dx12"] + +# We want the wgpu-core Vulkan backend on Unix (but not Emscripten) and Windows. +[target.'cfg(any(windows, all(unix, not(target_arch = "emscripten"))))'.dependencies.wgc] +workspace = true +features = ["vulkan"] [dependencies.wgt] workspace = true +# We need wgpu-hal unless we're targeting the web APIs. [target.'cfg(any(not(target_arch = "wasm32"), target_os = "emscripten"))'.dependencies.hal] workspace = true