Skip to content

Commit 2053358

Browse files
daxpeddaWumpf
andauthored
Add wgpu crate features for backends (#4815)
* Introduce `dx12` and `metal` crate features to `wgpu` * Implement dummy `Context` to allow compilation with `--no-default-features` * Address review * Remove `dummy::Context` in favor of `hal::api::Empty` * Add changelog entry * Panic early in `Instance::new()` if no backend is enabled Co-Authored-By: Andreas Reich <[email protected]> --------- Co-authored-by: Andreas Reich <[email protected]>
1 parent 855b069 commit 2053358

File tree

6 files changed

+78
-20
lines changed

6 files changed

+78
-20
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ Previously, `DeviceExt::create_texture_with_data` only allowed data to be provid
5555

5656
This feature allowed you to call `global_id` on any wgpu opaque handle to get a unique hashable identity for the given resource. This is now available without the feature flag. By @cwfitzgerald in [#4841](https://github.com/gfx-rs/wgpu/pull/4841)
5757

58+
### `dx12` and `metal` backend crate features
59+
60+
Wgpu now exposes backend feature for the Direct3D 12 (`dx12`) and Metal (`metal`) backend. These are enabled by default, but don't do anything when not targetting the corresponding OS. By @daxpedda in [#4815](https://github.com/gfx-rs/wgpu/pull/4815)
61+
5862
### New Features
5963

6064
#### General

wgpu-core/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@ define_backend_caller! { gfx_if_vulkan, gfx_if_vulkan_hidden, "vulkan" if all(fe
222222
define_backend_caller! { gfx_if_metal, gfx_if_metal_hidden, "metal" if all(feature = "metal", any(target_os = "macos", target_os = "ios")) }
223223
define_backend_caller! { gfx_if_dx12, gfx_if_dx12_hidden, "dx12" if all(feature = "dx12", windows) }
224224
define_backend_caller! { gfx_if_gles, gfx_if_gles_hidden, "gles" if feature = "gles" }
225+
define_backend_caller! { gfx_if_empty, gfx_if_empty_hidden, "empty" if all(
226+
not(any(feature = "metal", feature = "vulkan", feature = "gles")),
227+
any(target_os = "macos", target_os = "ios"),
228+
) }
225229

226230
/// Dispatch on an [`Id`]'s backend to a backend-generic method.
227231
///
@@ -276,6 +280,7 @@ macro_rules! gfx_select {
276280
wgt::Backend::Metal => $crate::gfx_if_metal!($global.$method::<$crate::api::Metal>( $($param),* )),
277281
wgt::Backend::Dx12 => $crate::gfx_if_dx12!($global.$method::<$crate::api::Dx12>( $($param),* )),
278282
wgt::Backend::Gl => $crate::gfx_if_gles!($global.$method::<$crate::api::Gles>( $($param),+ )),
283+
wgt::Backend::Empty => $crate::gfx_if_empty!($global.$method::<$crate::api::Empty>( $($param),+ )),
279284
other => panic!("Unexpected backend {:?}", other),
280285
}
281286
};

wgpu-hal/src/vulkan/instance.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ impl super::Instance {
507507
Ok(self.create_surface_from_vk_surface_khr(surface))
508508
}
509509

510-
#[cfg(any(target_os = "macos", target_os = "ios"))]
510+
#[cfg(all(any(target_os = "macos", target_os = "ios"), feature = "metal"))]
511511
fn create_surface_from_view(
512512
&self,
513513
view: *mut c_void,
@@ -805,13 +805,13 @@ impl crate::Instance<super::Api> for super::Instance {
805805
let hinstance = unsafe { GetModuleHandleW(std::ptr::null()) };
806806
self.create_surface_from_hwnd(hinstance as *mut _, handle.hwnd.get() as *mut _)
807807
}
808-
#[cfg(target_os = "macos")]
808+
#[cfg(all(target_os = "macos", feature = "metal"))]
809809
(Rwh::AppKit(handle), _)
810810
if self.shared.extensions.contains(&ext::MetalSurface::name()) =>
811811
{
812812
self.create_surface_from_view(handle.ns_view.as_ptr())
813813
}
814-
#[cfg(target_os = "ios")]
814+
#[cfg(all(target_os = "ios", feature = "metal"))]
815815
(Rwh::UiKit(handle), _)
816816
if self.shared.extensions.contains(&ext::MetalSurface::name()) =>
817817
{

wgpu/Cargo.toml

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ targets = [
2424
[lib]
2525

2626
[features]
27-
default = ["wgsl"]
27+
default = ["wgsl", "dx12", "metal"]
2828
# Apply run-time checks, even in release builds. These are in addition
2929
# to the validation carried out at public APIs in all builds.
3030
strict_asserts = ["wgc?/strict_asserts", "wgt/strict_asserts"]
@@ -33,11 +33,6 @@ glsl = ["naga/glsl-in"]
3333
wgsl = ["wgc?/wgsl"]
3434
trace = ["serde", "wgc/trace"]
3535
replay = ["serde", "wgc/replay"]
36-
# Enables the GLES backend on Windows & macOS
37-
angle = ["wgc/gles"]
38-
webgl = ["hal", "wgc/gles"]
39-
# Enables the Vulkan backend on macOS & iOS
40-
vulkan-portability = ["wgc/vulkan"]
4136
# Implement `Send` and `Sync` on Wasm.
4237
fragile-send-sync-non-atomic-wasm = [
4338
"hal/fragile-send-sync-non-atomic-wasm",
@@ -46,6 +41,17 @@ fragile-send-sync-non-atomic-wasm = [
4641
]
4742
# Log all API entry points at info instead of trace level.
4843
api_log_info = ["wgc/api_log_info"]
44+
# Backends
45+
# Enables the DX12 backend on Windows
46+
dx12 = ["wgc?/dx12"]
47+
# Enables the Metal backend on macOS & iOS
48+
metal = ["wgc?/metal"]
49+
# Enables the GLES backend on Windows & macOS
50+
angle = ["wgc?/gles"]
51+
# Enables the Vulkan backend on macOS & iOS
52+
vulkan-portability = ["wgc?/vulkan"]
53+
# Enables the GLES backend on Wasm (currently will also enable GLES dependencies on any other target)
54+
webgl = ["hal", "wgc/gles"]
4955

5056
# wgpu-core is always available as an optional dependency, "wgc".
5157
# Whenever wgpu-core is selected, we want raw window handle support.
@@ -60,15 +66,15 @@ features = ["raw-window-handle"]
6066
workspace = true
6167
features = ["raw-window-handle"]
6268

63-
# We want the wgpu-core Metal backend on macOS and iOS.
69+
# Enable `wgc` by default on macOS and iOS to allow the `metal` crate feature to
70+
# enable the Metal backend while being no-op on other targets.
6471
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgc]
6572
workspace = true
66-
features = ["metal"]
6773

6874
# We want the wgpu-core Direct3D backend and OpenGL (via WGL) on Windows.
6975
[target.'cfg(windows)'.dependencies.wgc]
7076
workspace = true
71-
features = ["dx12", "gles"]
77+
features = ["gles"]
7278

7379
# We want the wgpu-core Vulkan backend on Unix (but not emscripten, macOS, iOS) and Windows.
7480
[target.'cfg(any(windows, all(unix, not(target_os = "emscripten"), not(target_os = "ios"), not(target_os = "macos"))))'.dependencies.wgc]

wgpu/src/backend/direct.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ impl Context {
229229
self.0.generate_report()
230230
}
231231

232-
#[cfg(any(target_os = "ios", target_os = "macos"))]
232+
#[cfg(all(any(target_os = "ios", target_os = "macos"), feature = "metal"))]
233233
pub unsafe fn create_surface_from_core_animation_layer(
234234
&self,
235235
layer: *mut std::ffi::c_void,
@@ -265,7 +265,7 @@ impl Context {
265265
})
266266
}
267267

268-
#[cfg(target_os = "windows")]
268+
#[cfg(all(target_os = "windows", feature = "dx12"))]
269269
pub unsafe fn create_surface_from_visual(&self, visual: *mut std::ffi::c_void) -> Surface {
270270
let id = unsafe { self.0.instance_create_surface_from_visual(visual, ()) };
271271
Surface {
@@ -274,7 +274,7 @@ impl Context {
274274
}
275275
}
276276

277-
#[cfg(target_os = "windows")]
277+
#[cfg(all(target_os = "windows", feature = "dx12"))]
278278
pub unsafe fn create_surface_from_surface_handle(
279279
&self,
280280
surface_handle: *mut std::ffi::c_void,
@@ -289,7 +289,7 @@ impl Context {
289289
}
290290
}
291291

292-
#[cfg(target_os = "windows")]
292+
#[cfg(all(target_os = "windows", feature = "dx12"))]
293293
pub unsafe fn create_surface_from_swap_chain_panel(
294294
&self,
295295
swap_chain_panel: *mut std::ffi::c_void,

wgpu/src/lib.rs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1786,19 +1786,62 @@ impl Default for Instance {
17861786
/// Creates a new instance of wgpu with default options.
17871787
///
17881788
/// Backends are set to `Backends::all()`, and FXC is chosen as the `dx12_shader_compiler`.
1789+
///
1790+
/// # Panics
1791+
///
1792+
/// If no backend feature for the active target platform is enabled,
1793+
/// this method will panic, see [`Instance::any_backend_feature_enabled()`].
17891794
fn default() -> Self {
17901795
Self::new(InstanceDescriptor::default())
17911796
}
17921797
}
17931798

17941799
impl Instance {
1800+
/// Returns `true` if any backend feature is enabled for the current build configuration.
1801+
///
1802+
/// Which feature makes this method return true depends on the target platform:
1803+
/// * MacOS/iOS: `metal`, `vulkan-portability` or `angle`
1804+
/// * All other: Always returns true
1805+
///
1806+
/// TODO: Right now it's otherwise not possible yet to opt-out of all features on most platforms.
1807+
/// See <https://github.com/gfx-rs/wgpu/issues/3514>
1808+
/// * Windows: always enables Vulkan and GLES with no way to opt out
1809+
/// * Linux: always enables Vulkan and GLES with no way to opt out
1810+
/// * Web: either targets WebGPU backend or, if `webgl` enabled, WebGL
1811+
/// * TODO: Support both WebGPU and WebGL at the same time, see <https://github.com/gfx-rs/wgpu/issues/2804>
1812+
pub const fn any_backend_feature_enabled() -> bool {
1813+
// Method intentionally kept verbose to keep it a bit easier to follow!
1814+
1815+
// On macOS and iOS, at least one of Metal, Vulkan or GLES backend must be enabled.
1816+
let is_mac_or_ios = cfg!(target_os = "macos") || cfg!(target_os = "ios");
1817+
if is_mac_or_ios {
1818+
cfg!(feature = "metal")
1819+
|| cfg!(feature = "vulkan-portability")
1820+
|| cfg!(feature = "angle")
1821+
} else {
1822+
true
1823+
}
1824+
}
1825+
17951826
/// Create an new instance of wgpu.
17961827
///
17971828
/// # Arguments
17981829
///
17991830
/// - `instance_desc` - Has fields for which [backends][Backends] wgpu will choose
18001831
/// during instantiation, and which [DX12 shader compiler][Dx12Compiler] wgpu will use.
1832+
///
1833+
/// # Panics
1834+
///
1835+
/// If no backend feature for the active target platform is enabled,
1836+
/// this method will panic, see [`Instance::any_backend_feature_enabled()`].
18011837
pub fn new(instance_desc: InstanceDescriptor) -> Self {
1838+
if !Self::any_backend_feature_enabled() {
1839+
panic!(
1840+
"No wgpu backend feature that is implemented for the target platform was enabled. \
1841+
See `wgpu::Instance::any_backend_feature_enabled()` for more information."
1842+
);
1843+
}
1844+
18021845
Self {
18031846
context: Arc::from(crate::backend::Context::init(instance_desc)),
18041847
}
@@ -2029,7 +2072,7 @@ impl Instance {
20292072
/// # Safety
20302073
///
20312074
/// - layer must be a valid object to create a surface upon.
2032-
#[cfg(any(target_os = "ios", target_os = "macos"))]
2075+
#[cfg(all(any(target_os = "ios", target_os = "macos"), feature = "metal"))]
20332076
pub unsafe fn create_surface_from_core_animation_layer(
20342077
&self,
20352078
layer: *mut std::ffi::c_void,
@@ -2055,7 +2098,7 @@ impl Instance {
20552098
/// # Safety
20562099
///
20572100
/// - visual must be a valid IDCompositionVisual to create a surface upon.
2058-
#[cfg(target_os = "windows")]
2101+
#[cfg(all(target_os = "windows", feature = "dx12"))]
20592102
pub unsafe fn create_surface_from_visual(
20602103
&self,
20612104
visual: *mut std::ffi::c_void,
@@ -2081,7 +2124,7 @@ impl Instance {
20812124
/// # Safety
20822125
///
20832126
/// - surface_handle must be a valid SurfaceHandle to create a surface upon.
2084-
#[cfg(target_os = "windows")]
2127+
#[cfg(all(target_os = "windows", feature = "dx12"))]
20852128
pub unsafe fn create_surface_from_surface_handle(
20862129
&self,
20872130
surface_handle: *mut std::ffi::c_void,
@@ -2107,7 +2150,7 @@ impl Instance {
21072150
/// # Safety
21082151
///
21092152
/// - visual must be a valid SwapChainPanel to create a surface upon.
2110-
#[cfg(target_os = "windows")]
2153+
#[cfg(all(target_os = "windows", feature = "dx12"))]
21112154
pub unsafe fn create_surface_from_swap_chain_panel(
21122155
&self,
21132156
swap_chain_panel: *mut std::ffi::c_void,

0 commit comments

Comments
 (0)