Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wgpu crate features for backends #4815

Merged
merged 6 commits into from
Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ Previously, `DeviceExt::create_texture_with_data` only allowed data to be provid

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)

### `dx12` and `metal` backend crate features

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)

### New Features

#### General
Expand Down
5 changes: 5 additions & 0 deletions wgpu-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ define_backend_caller! { gfx_if_vulkan, gfx_if_vulkan_hidden, "vulkan" if all(fe
define_backend_caller! { gfx_if_metal, gfx_if_metal_hidden, "metal" if all(feature = "metal", any(target_os = "macos", target_os = "ios")) }
define_backend_caller! { gfx_if_dx12, gfx_if_dx12_hidden, "dx12" if all(feature = "dx12", windows) }
define_backend_caller! { gfx_if_gles, gfx_if_gles_hidden, "gles" if feature = "gles" }
define_backend_caller! { gfx_if_empty, gfx_if_empty_hidden, "empty" if all(
not(any(feature = "metal", feature = "vulkan", feature = "gles")),
any(target_os = "macos", target_os = "ios"),
) }

/// Dispatch on an [`Id`]'s backend to a backend-generic method.
///
Expand Down Expand Up @@ -276,6 +280,7 @@ macro_rules! gfx_select {
wgt::Backend::Metal => $crate::gfx_if_metal!($global.$method::<$crate::api::Metal>( $($param),* )),
wgt::Backend::Dx12 => $crate::gfx_if_dx12!($global.$method::<$crate::api::Dx12>( $($param),* )),
wgt::Backend::Gl => $crate::gfx_if_gles!($global.$method::<$crate::api::Gles>( $($param),+ )),
wgt::Backend::Empty => $crate::gfx_if_empty!($global.$method::<$crate::api::Empty>( $($param),+ )),
other => panic!("Unexpected backend {:?}", other),
}
};
Expand Down
6 changes: 3 additions & 3 deletions wgpu-hal/src/vulkan/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ impl super::Instance {
Ok(self.create_surface_from_vk_surface_khr(surface))
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
#[cfg(all(any(target_os = "macos", target_os = "ios"), feature = "metal"))]
fn create_surface_from_view(
&self,
view: *mut c_void,
Expand Down Expand Up @@ -805,13 +805,13 @@ impl crate::Instance<super::Api> for super::Instance {
let hinstance = unsafe { GetModuleHandleW(std::ptr::null()) };
self.create_surface_from_hwnd(hinstance as *mut _, handle.hwnd.get() as *mut _)
}
#[cfg(target_os = "macos")]
#[cfg(all(target_os = "macos", feature = "metal"))]
(Rwh::AppKit(handle), _)
if self.shared.extensions.contains(&ext::MetalSurface::name()) =>
{
self.create_surface_from_view(handle.ns_view.as_ptr())
}
#[cfg(target_os = "ios")]
#[cfg(all(target_os = "ios", feature = "metal"))]
(Rwh::UiKit(handle), _)
if self.shared.extensions.contains(&ext::MetalSurface::name()) =>
{
Expand Down
24 changes: 15 additions & 9 deletions wgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ targets = [
[lib]

[features]
default = ["wgsl"]
default = ["wgsl", "dx12", "metal"]
# 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 = ["wgc?/strict_asserts", "wgt/strict_asserts"]
Expand All @@ -33,11 +33,6 @@ glsl = ["naga/glsl-in"]
wgsl = ["wgc?/wgsl"]
trace = ["serde", "wgc/trace"]
replay = ["serde", "wgc/replay"]
# Enables the GLES backend on Windows & macOS
angle = ["wgc/gles"]
webgl = ["hal", "wgc/gles"]
# Enables the Vulkan backend on macOS & iOS
vulkan-portability = ["wgc/vulkan"]
# Implement `Send` and `Sync` on Wasm.
fragile-send-sync-non-atomic-wasm = [
"hal/fragile-send-sync-non-atomic-wasm",
Expand All @@ -46,6 +41,17 @@ fragile-send-sync-non-atomic-wasm = [
]
# Log all API entry points at info instead of trace level.
api_log_info = ["wgc/api_log_info"]
# Backends
daxpedda marked this conversation as resolved.
Show resolved Hide resolved
# Enables the DX12 backend on Windows
dx12 = ["wgc?/dx12"]
# Enables the Metal backend on macOS & iOS
metal = ["wgc?/metal"]
# Enables the GLES backend on Windows & macOS
angle = ["wgc?/gles"]
# Enables the Vulkan backend on macOS & iOS
vulkan-portability = ["wgc?/vulkan"]
# Enables the GLES backend on Wasm (currently will also enable GLES dependencies on any other target)
webgl = ["hal", "wgc/gles"]

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

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

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

# We want the wgpu-core Vulkan backend on Unix (but not emscripten, macOS, iOS) and Windows.
[target.'cfg(any(windows, all(unix, not(target_os = "emscripten"), not(target_os = "ios"), not(target_os = "macos"))))'.dependencies.wgc]
Expand Down
8 changes: 4 additions & 4 deletions wgpu/src/backend/direct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ impl Context {
self.0.generate_report()
}

#[cfg(any(target_os = "ios", target_os = "macos"))]
#[cfg(all(any(target_os = "ios", target_os = "macos"), feature = "metal"))]
pub unsafe fn create_surface_from_core_animation_layer(
&self,
layer: *mut std::ffi::c_void,
Expand Down Expand Up @@ -265,7 +265,7 @@ impl Context {
})
}

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

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

#[cfg(target_os = "windows")]
#[cfg(all(target_os = "windows", feature = "dx12"))]
pub unsafe fn create_surface_from_swap_chain_panel(
&self,
swap_chain_panel: *mut std::ffi::c_void,
Expand Down
51 changes: 47 additions & 4 deletions wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://github.com/gfx-rs/wgpu/issues/3514>
/// * 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 <https://github.com/gfx-rs/wgpu/issues/2804>
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)),
}
Expand Down Expand Up @@ -2029,7 +2072,7 @@ impl Instance {
/// # Safety
///
/// - layer must be a valid object to create a surface upon.
#[cfg(any(target_os = "ios", target_os = "macos"))]
#[cfg(all(any(target_os = "ios", target_os = "macos"), feature = "metal"))]
pub unsafe fn create_surface_from_core_animation_layer(
&self,
layer: *mut std::ffi::c_void,
Expand All @@ -2055,7 +2098,7 @@ impl Instance {
/// # Safety
///
/// - visual must be a valid IDCompositionVisual to create a surface upon.
#[cfg(target_os = "windows")]
#[cfg(all(target_os = "windows", feature = "dx12"))]
pub unsafe fn create_surface_from_visual(
&self,
visual: *mut std::ffi::c_void,
Expand All @@ -2081,7 +2124,7 @@ impl Instance {
/// # Safety
///
/// - surface_handle must be a valid SurfaceHandle to create a surface upon.
#[cfg(target_os = "windows")]
#[cfg(all(target_os = "windows", feature = "dx12"))]
pub unsafe fn create_surface_from_surface_handle(
&self,
surface_handle: *mut std::ffi::c_void,
Expand All @@ -2107,7 +2150,7 @@ impl Instance {
/// # Safety
///
/// - visual must be a valid SwapChainPanel to create a surface upon.
#[cfg(target_os = "windows")]
#[cfg(all(target_os = "windows", feature = "dx12"))]
pub unsafe fn create_surface_from_swap_chain_panel(
&self,
swap_chain_panel: *mut std::ffi::c_void,
Expand Down
Loading