diff --git a/CHANGELOG.md b/CHANGELOG.md index a903d4f5e..d04c43e68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,12 @@ also allows more easily creating these structures inline. By @cwfitzgerald in [#7133](https://github.com/gfx-rs/wgpu/pull/7133) +#### All Backends Now Have Features + +Previously, the `vulkan` and `gles` backends were non-optional on windows, linux, and android and there was no way to disable them. We have now figured out how to properly make them disablable! Additionally, if you turn on the `webgl` feature, you will only get the GLES backend on WebAssembly, it won't leak into native builds, like previously it might have. + +By @cwfitzgerald in [#7076](https://github.com/gfx-rs/wgpu/pull/7076). + #### `device.poll` Api Reworked This release reworked the poll api significantly to allow polling to return errors when polling hits internal timeout limits. diff --git a/Cargo.lock b/Cargo.lock index 004351f01..f74a0c5d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4509,7 +4509,6 @@ dependencies = [ "parking_lot", "profiling", "raw-window-handle 0.6.2", - "serde", "smallvec", "static_assertions", "wasm-bindgen", @@ -4559,10 +4558,42 @@ dependencies = [ "serde", "smallvec", "thiserror 2.0.11", + "wgpu-core-deps-apple", + "wgpu-core-deps-emscripten", + "wgpu-core-deps-wasm", + "wgpu-core-deps-windows-linux-android", "wgpu-hal", "wgpu-types", ] +[[package]] +name = "wgpu-core-deps-apple" +version = "24.0.0" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-emscripten" +version = "24.0.0" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-wasm" +version = "24.0.0" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-windows-linux-android" +version = "24.0.0" +dependencies = [ + "wgpu-hal", +] + [[package]] name = "wgpu-example-01-hello-compute" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index a3761ce5d..945f1c3ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ members = [ "player", "tests", "wgpu-core", + "wgpu-core/platform-deps/*", "wgpu-hal", "wgpu-info", "wgpu-macros", @@ -35,6 +36,7 @@ default-members = [ "player", "tests", "wgpu-core", + "wgpu-core/platform-deps/*", "wgpu-hal", "wgpu-info", "wgpu-macros", @@ -74,6 +76,11 @@ wgpu-macros = { version = "24.0.0", path = "./wgpu-macros" } wgpu-test = { version = "24.0.0", path = "./tests" } wgpu-types = { version = "24.0.0", path = "./wgpu-types" } +wgpu-core-deps-windows-linux-android = { version = "24.0.0", path = "./wgpu-core/platform-deps/windows-linux-android" } +wgpu-core-deps-apple = { version = "24.0.0", path = "./wgpu-core/platform-deps/apple" } +wgpu-core-deps-wasm = { version = "24.0.0", path = "./wgpu-core/platform-deps/wasm" } +wgpu-core-deps-emscripten = { version = "24.0.0", path = "./wgpu-core/platform-deps/emscripten" } + anyhow = { version = "1.0.95", default-features = false } approx = "0.5" argh = "0.1.13" diff --git a/wgpu-core/Cargo.toml b/wgpu-core/Cargo.toml index 29f1fd8df..863769913 100644 --- a/wgpu-core/Cargo.toml +++ b/wgpu-core/Cargo.toml @@ -35,10 +35,10 @@ unexpected_cfgs = { level = "warn", check-cfg = ['cfg(wgpu_validate_locks)'] } [lib] [features] -## Internally count resources and events for debugging purposes. If the counters -## feature is disabled, the counting infrastructure is removed from the build and -## the exposed counters always return 0. -counters = ["wgpu-types/counters"] +#! See docuemntation for the `wgpu` crate for more in-depth information on these features. + +#! ### Logging Configuration +# -------------------------------------------------------------------- ## Log all API entry points at info instead of trace level. ## Also, promotes certain debug log calls to info. @@ -47,17 +47,25 @@ api_log_info = [] ## Log resource lifecycle management at info instead of trace level. resource_log_info = [] -## Support the Renderdoc graphics debugger: -## -renderdoc = ["wgpu-hal/renderdoc"] +#! ### Runtime Checks +# -------------------------------------------------------------------- + +## Validates indirect draw/dispatch calls. This will also enable naga's +## WGSL frontend since we use a WGSL compute shader to do the validation. +indirect-validation = ["naga/wgsl-in"] ## 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 = ["wgpu-types/strict_asserts"] -## Validates indirect draw/dispatch calls. This will also enable naga's -## WGSL frontend since we use a WGSL compute shader to do the validation. -indirect-validation = ["naga/wgsl-in"] +#! ### Debugging +# -------------------------------------------------------------------- + +## Enable lock order observation. +observe_locks = ["dep:ron", "serde/serde_derive"] + +#! ### Serialization +# -------------------------------------------------------------------- ## Enables serialization via `serde` on common wgpu types. serde = ["dep:serde", "wgpu-types/serde", "arrayvec/serde", "hashbrown/serde"] @@ -65,15 +73,18 @@ serde = ["dep:serde", "wgpu-types/serde", "arrayvec/serde", "hashbrown/serde"] ## Enable API tracing. trace = ["dep:ron", "serde", "naga/serialize"] -## Enable lock order observation. -observe_locks = ["dep:ron", "serde/serde_derive"] - ## Enable API replaying replay = ["serde", "naga/deserialize"] -## Enable creating instances using raw-window-handle +#! ### Surface Support +# -------------------------------------------------------------------- + +## Enable creating surfaces using raw-window-handle raw-window-handle = ["dep:raw-window-handle"] +#! ### Shading Language Support +# -------------------------------------------------------------------- + ## Enable `ShaderModuleSource::Wgsl` wgsl = ["naga/wgsl-in"] @@ -83,40 +94,68 @@ glsl = ["naga/glsl-in"] ## Enable `ShaderModuleSource::SpirV` spirv = ["naga/spv-in", "dep:bytemuck"] -## Implement `Send` and `Sync` on Wasm, but only if atomics are not enabled. -## -## WebGL/WebGPU objects can not be shared between threads. -## However, it can be useful to artificially mark them as `Send` and `Sync` -## anyways to make it easier to write cross-platform code. -## This is technically *very* unsafe in a multithreaded environment, -## but on a wasm binary compiled without atomics we know we are definitely -## not in a multithreaded environment. -fragile-send-sync-non-atomic-wasm = [ - "wgpu-hal/fragile-send-sync-non-atomic-wasm", - "wgpu-types/fragile-send-sync-non-atomic-wasm", -] - -#! ### Backends, passed through to wgpu-hal +#! ### Other # -------------------------------------------------------------------- -## Enable the `metal` backend. -metal = ["wgpu-hal/metal"] +## Internally count resources and events for debugging purposes. If the counters +## feature is disabled, the counting infrastructure is removed from the build and +## the exposed counters always return 0. +counters = ["wgpu-types/counters"] -## Enable the `vulkan` backend. -vulkan = ["wgpu-hal/vulkan"] +## Implement `Send` and `Sync` on Wasm, but only if atomics are not enabled. +fragile-send-sync-non-atomic-wasm = [ + "wgpu-hal/fragile-send-sync-non-atomic-wasm", +] -## Enable the `GLES` backend. -## -## This is used for all of GLES, OpenGL, and WebGL. -gles = ["wgpu-hal/gles"] +#! ### External libraries +# -------------------------------------------------------------------- +#! The following features facilitate integration with third-party supporting libraries. -## Enable the `dx12` backend. -dx12 = ["wgpu-hal/dx12"] +## Enable using the `mach-dxcompiler-rs` crate to compile DX12 shaders. +static-dxc = ["wgpu-hal/static-dxc"] + +#! ### Target Conditional Features +# -------------------------------------------------------------------- +# Look to wgpu-hal's Cargo.toml for explaination how these features and the wgpu-core +# platform crates collude to provide platform-specific behavior. + +## DX12 backend +dx12 = ["wgpu-core-deps-windows-linux-android/dx12"] +## Metal backend +metal = ["wgpu-core-deps-apple/metal"] +## Vulkan backend, only available on Windows, Linux, Android +vulkan = ["wgpu-core-deps-windows-linux-android/vulkan"] +## OpenGL backend, only available on Windows, Linux, Android, and Emscripten +gles = [ + "wgpu-core-deps-windows-linux-android/gles", + "wgpu-core-deps-emscripten/gles", +] + +## WebGL backend, only available on Emscripten +webgl = ["wgpu-core-deps-wasm/webgl"] +## OpenGL backend, on macOS only +angle = ["wgpu-core-deps-apple/angle"] +## Vulkan portability backend, only available on macOS +vulkan-portability = ["wgpu-core-deps-apple/vulkan-portability"] +## Renderdoc integration, only available on Windows, Linux, and Android +renderdoc = ["wgpu-core-deps-windows-linux-android/renderdoc"] ## Enable the `noop` backend. # TODO(https://github.com/gfx-rs/wgpu/issues/7120): there should be a hal feature noop = [] +# The target limitation here isn't needed, but prevents more than one of these +# platform crates from being included in the build at a time, preventing users +# from getting confused by seeing them in the list of crates. +[target.'cfg(target_vendor = "apple")'.dependencies] +wgpu-core-deps-apple = { workspace = true, optional = true } +[target.'cfg(target_os = "emscripten")'.dependencies] +wgpu-core-deps-emscripten = { workspace = true, optional = true } +[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] +wgpu-core-deps-wasm = { workspace = true, optional = true } +[target.'cfg(any(windows, target_os = "linux", target_os = "android"))'.dependencies] +wgpu-core-deps-windows-linux-android = { workspace = true, optional = true } + [dependencies] naga.workspace = true wgpu-hal.workspace = true diff --git a/wgpu-core/build.rs b/wgpu-core/build.rs index 4d3548167..55c43fba2 100644 --- a/wgpu-core/build.rs +++ b/wgpu-core/build.rs @@ -1,13 +1,22 @@ fn main() { cfg_aliases::cfg_aliases! { + windows_linux_android: { any(windows, target_os = "linux", target_os = "android") }, send_sync: { any( not(target_arch = "wasm32"), all(feature = "fragile-send-sync-non-atomic-wasm", not(target_feature = "atomics")) ) }, - webgl: { all(target_arch = "wasm32", not(target_os = "emscripten"), gles) }, dx12: { all(target_os = "windows", feature = "dx12") }, - gles: { all(feature = "gles") }, + webgl: { all(target_arch = "wasm32", not(target_os = "emscripten"), feature = "webgl") }, + gles: { any( + all(windows_linux_android, feature = "gles"), // Regular GLES + all(webgl), // WebGL + all(target_os = "emscripten", feature = "gles"), // Emscripten GLES + all(target_vendor = "apple", feature = "angle") // ANGLE on Apple + ) }, + vulkan: { any( + all(windows_linux_android, feature = "vulkan"), // Regular Vulkan + all(target_vendor = "apple", feature = "vulkan-portability") // Vulkan Portability on Apple + ) }, metal: { all(target_vendor = "apple", feature = "metal") }, - vulkan: { all(not(target_arch = "wasm32"), feature = "vulkan") } } } diff --git a/wgpu-core/platform-deps/apple/Cargo.toml b/wgpu-core/platform-deps/apple/Cargo.toml new file mode 100644 index 000000000..9734162ff --- /dev/null +++ b/wgpu-core/platform-deps/apple/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "wgpu-core-deps-apple" +version.workspace = true +authors.workspace = true +edition.workspace = true +description = "Feature unification helper crate for Apple platforms" +homepage.workspace = true +repository.workspace = true +keywords.workspace = true +license.workspace = true +readme = "README.md" + +# Override the workspace's `rust-version` key. Firefox uses `cargo vendor` to +# copy the crates it actually uses out of the workspace, so it's meaningful for +# them to have less restrictive MSRVs individually than the workspace as a +# whole, if their code permits. See `../README.md` for details. +rust-version = "1.76" + +[features] +metal = ["wgpu-hal/metal"] +angle = ["wgpu-hal/gles", "wgpu-hal/renderdoc"] +vulkan-portability = ["wgpu-hal/vulkan", "wgpu-hal/renderdoc"] + +# Depend on wgpu-hal conditionally, so that the above features only apply to wgpu-hal on this set of platforms. +[target.'cfg(target_vendor = "apple")'.dependencies] +wgpu-hal.workspace = true diff --git a/wgpu-core/platform-deps/apple/README.md b/wgpu-core/platform-deps/apple/README.md new file mode 100644 index 000000000..5123eeb29 --- /dev/null +++ b/wgpu-core/platform-deps/apple/README.md @@ -0,0 +1,3 @@ +This crate exists to allow platform and feature specific features work correctly. The features +enabled on this crate are only enabled on `target_vendor = "apple"` platforms. See wgpu-hal's `Cargo.toml` +for more information. \ No newline at end of file diff --git a/wgpu-core/platform-deps/apple/src/lib.rs b/wgpu-core/platform-deps/apple/src/lib.rs new file mode 100644 index 000000000..59fddaa92 --- /dev/null +++ b/wgpu-core/platform-deps/apple/src/lib.rs @@ -0,0 +1,3 @@ +//! This crate exists to allow platform and feature specific features work correctly. The features +//! enabled on this crate are only enabled on `target_vendor = "apple"` platforms. See wgpu-hal's `Cargo.toml` +//! for more information. diff --git a/wgpu-core/platform-deps/emscripten/Cargo.toml b/wgpu-core/platform-deps/emscripten/Cargo.toml new file mode 100644 index 000000000..d38ceb9bc --- /dev/null +++ b/wgpu-core/platform-deps/emscripten/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "wgpu-core-deps-emscripten" +version.workspace = true +authors.workspace = true +edition.workspace = true +description = "Feature unification helper crate for the Emscripten platform" +homepage.workspace = true +repository.workspace = true +keywords.workspace = true +license.workspace = true +readme = "README.md" + +# Override the workspace's `rust-version` key. Firefox uses `cargo vendor` to +# copy the crates it actually uses out of the workspace, so it's meaningful for +# them to have less restrictive MSRVs individually than the workspace as a +# whole, if their code permits. See `../README.md` for details. +rust-version = "1.76" + +[features] +gles = ["wgpu-hal/gles"] + +# Depend on wgpu-hal conditionally, so that the above features only apply to wgpu-hal on this set of platforms. +[target.'cfg(target_os = "emscripten")'.dependencies] +wgpu-hal.workspace = true diff --git a/wgpu-core/platform-deps/emscripten/README.md b/wgpu-core/platform-deps/emscripten/README.md new file mode 100644 index 000000000..46a8dce22 --- /dev/null +++ b/wgpu-core/platform-deps/emscripten/README.md @@ -0,0 +1,3 @@ +This crate exists to allow platform and feature specific features work correctly. The features +enabled on this crate are only enabled on `target_os = "emscripten"` platforms. +See wgpu-hal's `Cargo.toml` for more information. diff --git a/wgpu-core/platform-deps/emscripten/src/lib.rs b/wgpu-core/platform-deps/emscripten/src/lib.rs new file mode 100644 index 000000000..d969cf885 --- /dev/null +++ b/wgpu-core/platform-deps/emscripten/src/lib.rs @@ -0,0 +1,3 @@ +//! This crate exists to allow platform and feature specific features work correctly. The features +//! enabled on this crate are only enabled on `target_os = "emscripten"` platforms. +//! See wgpu-hal's `Cargo.toml` for more information. diff --git a/wgpu-core/platform-deps/wasm/Cargo.toml b/wgpu-core/platform-deps/wasm/Cargo.toml new file mode 100644 index 000000000..a318f38f5 --- /dev/null +++ b/wgpu-core/platform-deps/wasm/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "wgpu-core-deps-wasm" +version.workspace = true +authors.workspace = true +edition.workspace = true +description = "Feature unification helper crate for the WebAssembly platform" +homepage.workspace = true +repository.workspace = true +keywords.workspace = true +license.workspace = true +readme = "README.md" + +# Override the workspace's `rust-version` key. Firefox uses `cargo vendor` to +# copy the crates it actually uses out of the workspace, so it's meaningful for +# them to have less restrictive MSRVs individually than the workspace as a +# whole, if their code permits. See `../README.md` for details. +rust-version = "1.76" + +[features] +webgl = ["wgpu-hal/gles"] + +# Depend on wgpu-hal conditionally, so that the above features only apply to wgpu-hal on this set of platforms. +[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] +wgpu-hal.workspace = true diff --git a/wgpu-core/platform-deps/wasm/README.md b/wgpu-core/platform-deps/wasm/README.md new file mode 100644 index 000000000..39e1ff1b5 --- /dev/null +++ b/wgpu-core/platform-deps/wasm/README.md @@ -0,0 +1,3 @@ +This crate exists to allow platform and feature specific features work correctly. The features +enabled on this crate are only enabled on `target_arch = "wasm32"` platforms. See wgpu-hal's `Cargo.toml` +for more information. diff --git a/wgpu-core/platform-deps/wasm/src/lib.rs b/wgpu-core/platform-deps/wasm/src/lib.rs new file mode 100644 index 000000000..6c03e6e5f --- /dev/null +++ b/wgpu-core/platform-deps/wasm/src/lib.rs @@ -0,0 +1,3 @@ +//! This crate exists to allow platform and feature specific features work correctly. The features +//! enabled on this crate are only enabled on `target_arch = "wasm32"` platforms. See wgpu-hal's `Cargo.toml` +//! for more information. diff --git a/wgpu-core/platform-deps/windows-linux-android/Cargo.toml b/wgpu-core/platform-deps/windows-linux-android/Cargo.toml new file mode 100644 index 000000000..7de228cdf --- /dev/null +++ b/wgpu-core/platform-deps/windows-linux-android/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "wgpu-core-deps-windows-linux-android" +version.workspace = true +authors.workspace = true +edition.workspace = true +description = "Feature unification helper crate for the Windows/Linux/Android platforms" +homepage.workspace = true +repository.workspace = true +keywords.workspace = true +license.workspace = true +readme = "README.md" + +# Override the workspace's `rust-version` key. Firefox uses `cargo vendor` to +# copy the crates it actually uses out of the workspace, so it's meaningful for +# them to have less restrictive MSRVs individually than the workspace as a +# whole, if their code permits. See `../README.md` for details. +rust-version = "1.76" + +[features] +gles = ["wgpu-hal/gles"] +vulkan = ["wgpu-hal/vulkan"] +dx12 = ["wgpu-hal/dx12"] +renderdoc = ["wgpu-hal/renderdoc"] + +# Depend on wgpu-hal conditionally, so that the above features only apply to wgpu-hal on this set of platforms. +[target.'cfg(any(windows, target_os = "linux", target_os = "android"))'.dependencies] +wgpu-hal.workspace = true diff --git a/wgpu-core/platform-deps/windows-linux-android/README.md b/wgpu-core/platform-deps/windows-linux-android/README.md new file mode 100644 index 000000000..fdc9f9d3a --- /dev/null +++ b/wgpu-core/platform-deps/windows-linux-android/README.md @@ -0,0 +1,3 @@ +This crate exists to allow platform and feature specific features work correctly. The features +enabled on this crate are only enabled on `windows`, `target_os = "linux"`, and `target_os = "android"` +platforms. See wgpu-hal's `Cargo.toml` for more information. diff --git a/wgpu-core/platform-deps/windows-linux-android/src/lib.rs b/wgpu-core/platform-deps/windows-linux-android/src/lib.rs new file mode 100644 index 000000000..2b06dda01 --- /dev/null +++ b/wgpu-core/platform-deps/windows-linux-android/src/lib.rs @@ -0,0 +1,3 @@ +//! This crate exists to allow platform and feature specific features work correctly. The features +//! enabled on this crate are only enabled on `windows`, `target_os = "linux"`, and `target_os = "android"` +//! platforms. See wgpu-hal's `Cargo.toml` for more information. diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index e3056e2c7..9255d507a 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -40,51 +40,98 @@ unexpected_cfgs = { level = "warn", check-cfg = ['cfg(web_sys_unstable_apis)'] } [lib] [features] + +######################## +### Backend Features ### +######################## + +# The interaction of features between wgpu-core and wgpu-hal is a bit nuanced to get +# the desired behavior on all platforms. +# +# At the wgpu-hal level the features are defined to enable the backends on all platforms +# that can compile the backend. Vulkan for example will have an effect on Windows, Mac, Linux, and Android. +# This is done with target conditional dependencies in wgpu-hal. This allows `--all-features` +# to compile on all platforms. +# +# wgpu-core's features are defined to enable the backends on their "default" platforms. For example we +# exclude the Vulkan backend on MacOS unless a separate feature `vulkan-portability` is enabled. In response +# to these features, it enables features of platform specific crates. For example, the `vulkan` feature in wgpu-core +# enables the `vulkan` feature in `wgpu-core-deps-windows-linux-android` which in turn enables the +# `vulkan` feature in `wgpu-hal` _only_ on those platforms. If you enable the `vulkan-portability` feature, it +# will enable the `vulkan` feature in `wgpu-core-deps-apple`. The only way to do this is unfortunately to have +# a separate crate for each platform category that participates in the feature unification. +# +# This trick doesn't work at the `wgpu` level, because the `wgpu` -> `wgpu-core` dependency is conditional, +# making the Cargo.toml signifigantly more complicated in all areas. +# +# See https://github.com/gfx-rs/wgpu/issues/3514, https://github.com/gfx-rs/wgpu/pull/7076, +# and https://github.com/rust-lang/cargo/issues/1197 for more information. + ## Enables the Metal backend when targeting Apple platforms. -## -## Has no effect on non-Apple platforms. metal = [ # Metal is only available on Apple platforms, therefore request MSL output also only if we target an Apple platform. - "naga/msl-out-if-target-apple", + "naga/msl-out", + "dep:arrayvec", "dep:block", + "dep:core-graphics-types", + "dep:hashbrown", + "dep:libc", + "dep:log", + "dep:metal", + "dep:objc", + "dep:profiling", ] vulkan = [ "naga/spv-out", + "dep:android_system_properties", + "dep:arrayvec", "dep:ash", "dep:gpu-alloc", "dep:gpu-descriptor", + "dep:hashbrown", + "dep:libc", "dep:libloading", - "dep:smallvec", - "dep:android_system_properties", + "dep:log", "dep:ordered-float", + "dep:profiling", + "dep:smallvec", + "dep:windows", + "windows/Win32", ] gles = [ "naga/glsl-out", - "once_cell/std", + "dep:arrayvec", "dep:bytemuck", "dep:glow", "dep:glutin_wgl_sys", + "dep:hashbrown", + "dep:js-sys", "dep:khronos-egl", "dep:libloading", + "dep:log", "dep:ndk-sys", - "dep:once_cell", + "dep:profiling", + "dep:wasm-bindgen", + "dep:web-sys", + "once_cell/std", "windows/Win32_Graphics_OpenGL", "windows/Win32_Graphics_Gdi", "windows/Win32_System_LibraryLoader", "windows/Win32_UI_WindowsAndMessaging", ] ## Enables the DX12 backend when targeting Windows. -## -## Has no effect if not targeting Windows. dx12 = [ - # DX12 is only available on Windows, therefore request HLSL output also only if we target Windows. + "naga/hlsl-out", + "dep:arrayvec", "dep:bit-set", + "dep:hashbrown", "dep:libloading", + "dep:log", + "dep:ordered-float", + "dep:profiling", "dep:range-alloc", "dep:windows-core", - "dep:ordered-float", "gpu-allocator/d3d12", - "naga/hlsl-out-if-target-windows", "windows/Win32_Graphics_Direct3D_Fxc", "windows/Win32_Graphics_Direct3D_Dxc", "windows/Win32_Graphics_Direct3D", @@ -98,12 +145,21 @@ dx12 = [ "windows/Win32_System_Threading", "windows/Win32_UI_WindowsAndMessaging", ] -## Enables statically linking DXC. + +########################### +### Misc Other Features ### +########################### + static-dxc = ["dep:mach-dxcompiler-rs"] -renderdoc = ["dep:libloading", "dep:renderdoc-sys"] +renderdoc = ["dep:libloading", "dep:renderdoc-sys", "dep:log"] fragile-send-sync-non-atomic-wasm = [ "wgpu-types/fragile-send-sync-non-atomic-wasm", ] + +################################### +### Internal Debugging Features ### +################################### + # Panic when running into an out-of-memory error (for debugging purposes). # # Only affects the d3d12 and vulkan backends. @@ -132,17 +188,20 @@ required-features = ["gles"] naga.workspace = true wgpu-types.workspace = true -arrayvec.workspace = true +# Dependencies in the lib and empty backend bitflags.workspace = true -hashbrown.workspace = true -log.workspace = true +raw-window-handle.workspace = true +parking_lot.workspace = true +thiserror.workspace = true + +# Target agnostic dependencies used only in backends. +arrayvec = { workspace = true, optional = true } +hashbrown = { workspace = true, optional = true } +log = { workspace = true, optional = true } once_cell = { workspace = true, optional = true } ordered-float = { workspace = true, optional = true } -parking_lot.workspace = true -profiling = { workspace = true, default-features = false } -raw-window-handle.workspace = true -rustc-hash.workspace = true -thiserror.workspace = true +profiling = { workspace = true, optional = true, default-features = false } +rustc-hash = { workspace = true, optional = true } # Backend: GLES bytemuck = { workspace = true, optional = true } @@ -169,7 +228,7 @@ renderdoc-sys = { workspace = true, optional = true } [target.'cfg(unix)'.dependencies] # Backend: Vulkan -libc.workspace = true +libc = { workspace = true, optional = true } ######################### ### Platform: Windows ### @@ -200,9 +259,9 @@ mach-dxcompiler-rs = { workspace = true, optional = true } [target.'cfg(target_vendor = "apple")'.dependencies] # Backend: Metal block = { workspace = true, optional = true } -core-graphics-types.workspace = true -metal.workspace = true -objc.workspace = true +core-graphics-types = { workspace = true, optional = true } +metal = { workspace = true, optional = true } +objc = { workspace = true, optional = true } ######################### ### Platform: Android ### @@ -218,15 +277,15 @@ ndk-sys = { workspace = true, optional = true } [target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] # Backend: GLES -wasm-bindgen.workspace = true -web-sys = { workspace = true, features = [ +wasm-bindgen = { workspace = true, optional = true } +web-sys = { workspace = true, optional = true, features = [ "default", "Window", "HtmlCanvasElement", "WebGl2RenderingContext", "OffscreenCanvas", ] } -js-sys = { workspace = true, features = ["default"] } +js-sys = { workspace = true, optional = true, features = ["default"] } ############################ ### Platform: Emscripten ### @@ -234,7 +293,10 @@ js-sys = { workspace = true, features = ["default"] } [target.'cfg(target_os = "emscripten")'.dependencies] # Backend: GLES -khronos-egl = { workspace = true, features = ["static", "no-pkg-config"] } +khronos-egl = { workspace = true, optional = true, features = [ + "static", + "no-pkg-config", +] } # Note: it's unused by emscripten, but we keep it to have single code base in egl.rs libloading = { workspace = true, optional = true } diff --git a/wgpu-hal/src/auxil/renderdoc.rs b/wgpu-hal/src/auxil/renderdoc.rs index 619c4b895..c5fa96c79 100644 --- a/wgpu-hal/src/auxil/renderdoc.rs +++ b/wgpu-hal/src/auxil/renderdoc.rs @@ -1,4 +1,5 @@ //! RenderDoc integration - +#![cfg_attr(not(any(feature = "gles", feature = "vulkan")), allow(dead_code))] use alloc::string::String; use core::{ffi, ptr}; diff --git a/wgpu-types/Cargo.toml b/wgpu-types/Cargo.toml index 1c63eb7b5..7b95565da 100644 --- a/wgpu-types/Cargo.toml +++ b/wgpu-types/Cargo.toml @@ -40,7 +40,7 @@ default = ["std"] std = ["js-sys/std", "web-sys/std", "thiserror/std"] strict_asserts = [] fragile-send-sync-non-atomic-wasm = [] -serde = ["dep:serde"] +serde = ["dep:serde", "bitflags/serde"] # Enables some internal instrumentation for debugging purposes. counters = [] diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 5574fd5ee..aa6f25d05 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -29,13 +29,10 @@ ignored = ["cfg_aliases"] [lib] [features] -default = ["wgsl", "dx12", "metal", "webgpu"] +default = ["dx12", "metal", "gles", "vulkan", "wgsl", "webgpu"] #! ### Backends # -------------------------------------------------------------------- -#! ⚠️ WIP: Not all backends can be manually configured today. -#! On Windows, Linux & Android the Vulkan & GLES backends are always enabled. -#! See [#3514](https://github.com/gfx-rs/wgpu/issues/3514) for more details. ## Enables the DX12 backend on Windows. dx12 = ["wgpu-core?/dx12"] @@ -43,19 +40,35 @@ dx12 = ["wgpu-core?/dx12"] ## Enables the Metal backend on macOS & iOS. metal = ["wgpu-core?/metal"] -## Enables the WebGPU backend on Wasm. Disabled when targeting `emscripten`. -webgpu = ["naga?/wgsl-out"] +## Enables the Vulkan backend on Windows, Linux, and Android. +vulkan = ["wgpu-core?/vulkan"] -## Enables the GLES backend via [ANGLE](https://github.com/google/angle) on macOS using. -angle = ["wgpu-core?/gles"] +## Enables the OpenGL/GLES backend on Windows, Linux, Android, and Emscripten. +gles = ["wgpu-core?/gles"] -## Enables the Vulkan backend on macOS & iOS. -vulkan-portability = ["wgpu-core?/vulkan"] +## Enables the WebGPU backend on WebAssembly. +webgpu = [ + "naga?/wgsl-out", + "dep:wasm-bindgen-futures", + "web-sys/Document", + "web-sys/Event", + "web-sys/Navigator", + "web-sys/NodeList", + "web-sys/Window", + "web-sys/WorkerGlobalScope", + "web-sys/WorkerNavigator", +] -## Enables the GLES backend on Wasm -## -## * ⚠️ WIP: Currently will also enable GLES dependencies on any other targets. -webgl = ["dep:wgpu-hal", "wgpu-core/gles"] +#! ### Conditional Backends + +## Enables the GLES backend on macOS only for use with [ANGLE](https://github.com/google/angle). +angle = ["wgpu-core?/angle"] + +## Enables the Vulkan backend on macOS & iOS only for use with [MoltenVK](https://github.com/KhronosGroup/MoltenVK). +vulkan-portability = ["wgpu-core?/vulkan-portability"] + +## Enables the GLES backend on WebAssembly only. +webgl = ["wgpu-core/webgl", "dep:wgpu-hal", "dep:smallvec"] ## Enables the noop backend for testing. ## @@ -71,6 +84,8 @@ noop = ["wgpu-core/noop"] #! ### Shading language support # -------------------------------------------------------------------- +#! These features enable support for that input language on all platforms. +#! We will translate the input language to whatever the backend requires. ## Enable accepting SPIR-V shaders as input. spirv = ["naga/spv-in", "wgpu-core?/spirv"] @@ -84,24 +99,32 @@ wgsl = ["wgpu-core?/wgsl"] ## Enable accepting naga IR shaders as input. naga-ir = ["dep:naga"] -#! ### Logging & Tracing +#! ### Assertions and Serialization # -------------------------------------------------------------------- -#! The following features do not have any effect on the WebGPU backend. - ## 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 = ["wgpu-core?/strict_asserts", "wgpu-types/strict_asserts"] ## Enables serialization via `serde` on common wgpu types. -serde = ["dep:serde", "wgpu-core?/serde"] +serde = ["wgpu-core?/serde", "wgpu-types/serde"] # Uncomment once we get to https://github.com/gfx-rs/wgpu/issues/5974 # ## Allow writing of trace capture files. See [`Adapter::request_device`]. # trace = ["serde", "wgpu-core/trace"] -## Allow deserializing of trace capture files that were written with the `trace` feature. -## To replay a trace file use the [wgpu player](https://github.com/gfx-rs/wgpu/tree/trunk/player). -replay = ["serde", "wgpu-core?/replay"] +#! ### External libraries +# -------------------------------------------------------------------- +#! The following features facilitate integration with third-party supporting libraries. + +## Enables statically linking DXC. +## +## Normally, to use the modern DXC shader compiler with WGPU, the final application +## must be shipped alongside `dxcompiler.dll` and `dxil.dll` (which can be downloaded from [Microsoft's GitHub][dxc]). +## This feature statically links a version of DXC so that no external binaries are required +## to compile DX12 shaders. +## +## [dxc]: https://github.com/Microsoft/DirectXShaderCompiler +static-dxc = ["wgpu-core?/static-dxc"] #! ### Other # -------------------------------------------------------------------- @@ -117,26 +140,12 @@ counters = ["wgpu-core?/counters"] ## However, it can be useful to artificially mark them as `Send` and `Sync` ## anyways to make it easier to write cross-platform code. ## This is technically *very* unsafe in a multithreaded environment, -## but on a wasm binary compiled without atomics we know we are definitely -## not in a multithreaded environment. +## but on a wasm binary compiled without atomics is a definitionally single-threaded environment. fragile-send-sync-non-atomic-wasm = [ - "wgpu-hal?/fragile-send-sync-non-atomic-wasm", "wgpu-core?/fragile-send-sync-non-atomic-wasm", "wgpu-types/fragile-send-sync-non-atomic-wasm", ] - -#! ### External libraries -# -------------------------------------------------------------------- -#! The following features facilitate integration with third-party supporting libraries. - -## Enables statically linking DXC. -## Normally, to use the modern DXC shader compiler with WGPU, the final application -## must be shipped alongside `dxcompiler.dll` and `dxil.dll` (which can be downloaded from Microsoft's GitHub). -## This feature statically links a version of DXC so that no external binaries are required -## to compile DX12 shaders. -static-dxc = ["wgpu-hal?/static-dxc"] - ######################### # Standard Dependencies # ######################### @@ -144,8 +153,9 @@ static-dxc = ["wgpu-hal?/static-dxc"] [dependencies] naga = { workspace = true, optional = true } wgpu-core = { workspace = true, optional = true } -wgpu-types = { workspace = true, features = ["serde"] } +wgpu-types.workspace = true +# Needed for both wgpu-core and webgpu arrayvec.workspace = true bitflags.workspace = true document-features.workspace = true @@ -154,70 +164,57 @@ log.workspace = true parking_lot.workspace = true profiling.workspace = true raw-window-handle = { workspace = true, features = ["std"] } -serde = { workspace = true, features = ["default", "derive"], optional = true } -smallvec.workspace = true static_assertions.workspace = true ######################################## # Target Specific Feature Dependencies # ######################################## -# Windows -[target.'cfg(windows)'.dependencies] +################### +# Not Webassembly # +################### +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +# Needed for only wgpu-core backend. Not optional as only wgpu-core backend exists on native platforms. wgpu-core = { workspace = true, features = [ "raw-window-handle", - "vulkan", - "gles", + "renderdoc", + "indirect-validation", ] } -wgpu-hal = { workspace = true, features = ["renderdoc"] } +wgpu-hal.workspace = true -# Apple Platforms -[target.'cfg(target_vendor = "apple")'.dependencies] -wgpu-core = { workspace = true, features = ["raw-window-handle"] } -wgpu-hal = { workspace = true, features = [] } +smallvec.workspace = true -# Linux + Android -[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] -wgpu-core = { workspace = true, features = [ - "raw-window-handle", - "vulkan", - "gles", -] } -wgpu-hal = { workspace = true, features = ["renderdoc"] } - -# Webassembly +############### +# Webassembly # +############### [target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] +# Needed for all backends +js-sys = { workspace = true, features = ["default"] } +wasm-bindgen.workspace = true +web-sys = { workspace = true, features = [ + "HtmlCanvasElement", + "OffscreenCanvas", +] } + +# Needed for only wgpu-core backend. Optional as webgl is optional on WebAssembly. wgpu-core = { workspace = true, optional = true, features = [ "raw-window-handle", ] } wgpu-hal = { workspace = true, optional = true } -js-sys = { workspace = true, features = ["default"] } -parking_lot.workspace = true -wasm-bindgen-futures.workspace = true -wasm-bindgen.workspace = true -web-sys = { workspace = true, features = [ - "default", - "Document", - "Navigator", - "Node", - "NodeList", - "HtmlCanvasElement", - "OffscreenCanvas", - "ImageBitmap", - "ImageBitmapRenderingContext", - "Window", - "WorkerGlobalScope", - "WorkerNavigator", - # Needed by webgpu_sys - "Event", - "EventTarget", -] } +smallvec = { workspace = true, optional = true } -# Emscripten +# Needed for the webgpu backend. Optional as webgpu is optional on WebAssembly. +wasm-bindgen-futures = { workspace = true, optional = true } + +############## +# Emscripten # +############## [target.'cfg(target_os = "emscripten")'.dependencies] -wgpu-core = { workspace = true, features = ["raw-window-handle", "gles"] } -wgpu-hal = { workspace = true } +wgpu-core = { workspace = true, features = ["raw-window-handle"] } +wgpu-hal.workspace = true + +smallvec.workspace = true [build-dependencies] cfg_aliases.workspace = true diff --git a/xtask/src/check_feature_dependencies.rs b/xtask/src/check_feature_dependencies.rs index 6601bc63b..3a1e4c3f0 100644 --- a/xtask/src/check_feature_dependencies.rs +++ b/xtask/src/check_feature_dependencies.rs @@ -3,7 +3,6 @@ use xshell::Shell; #[derive(Debug)] enum Search<'a> { - #[expect(dead_code)] Positive(&'a str), Negative(&'a str), } @@ -30,7 +29,6 @@ const ALL_WGPU_FEATURES: &[&str] = &[ "wgsl", "naga-ir", "serde", - "replay", "counters", "fragile-send-sync-non-atomic-wasm", "static-dxc", @@ -63,6 +61,100 @@ pub fn check_feature_dependencies(shell: Shell, arguments: Arguments) -> anyhow: default_features: false, search_terms: &[Search::Negative("naga")], }, + Requirement { + human_readable_name: "wasm32 with `webgl` feature depends on `glow`", + target: "wasm32-unknown-unknown", + packages: &["wgpu"], + features: &["webgl"], + default_features: false, + search_terms: &[Search::Positive("glow")], + }, + Requirement { + human_readable_name: "windows with `webgl` does not depend on `glow`", + target: "x86_64-pc-windows-msvc", + packages: &["wgpu"], + features: &["webgl"], + default_features: false, + search_terms: &[Search::Negative("glow")], + }, + Requirement { + human_readable_name: "apple with `vulkan` feature does not depend on `ash`", + target: "aarch64-apple-darwin", + packages: &["wgpu"], + features: &["vulkan"], + default_features: false, + search_terms: &[Search::Negative("ash")], + }, + Requirement { + human_readable_name: + "apple with `vulkan-portability` feature depends on `ash` and `renderdoc-sys`", + target: "aarch64-apple-darwin", + packages: &["wgpu"], + features: &["vulkan-portability"], + default_features: false, + search_terms: &[Search::Positive("ash"), Search::Positive("renderdoc-sys")], + }, + Requirement { + human_readable_name: "apple with 'gles' feature does not depend on 'glow'", + target: "aarch64-apple-darwin", + packages: &["wgpu"], + features: &["gles"], + default_features: false, + search_terms: &[Search::Negative("glow")], + }, + Requirement { + human_readable_name: "apple with 'angle' feature depends on 'glow' and `renderdoc-sys`", + target: "aarch64-apple-darwin", + packages: &["wgpu"], + features: &["angle"], + default_features: false, + search_terms: &[Search::Positive("glow"), Search::Positive("renderdoc-sys")], + }, + Requirement { + human_readable_name: "apple with no features does not depend on 'renderdoc-sys'", + target: "aarch64-apple-darwin", + packages: &["wgpu"], + features: &[], + default_features: false, + search_terms: &[Search::Negative("renderdoc-sys")], + }, + Requirement { + human_readable_name: + "windows with no features does not depend on 'glow', `windows`, or `ash`", + target: "x86_64-pc-windows-msvc", + packages: &["wgpu"], + features: &[], + default_features: false, + search_terms: &[ + Search::Negative("glow"), + Search::Negative("windows"), + Search::Negative("ash"), + ], + }, + Requirement { + human_readable_name: "windows with no features depends on renderdoc-sys", + target: "x86_64-pc-windows-msvc", + packages: &["wgpu"], + features: &[], + default_features: false, + search_terms: &[Search::Positive("renderdoc-sys")], + }, + Requirement { + human_readable_name: "emscripten with webgl feature does not depend on glow", + target: "wasm32-unknown-emscripten", + packages: &["wgpu"], + features: &["webgl"], + default_features: false, + search_terms: &[Search::Negative("glow")], + }, + Requirement { + human_readable_name: "emscripten with gles feature depends on glow", + target: "wasm32-unknown-emscripten", + packages: &["wgpu"], + features: &["gles"], + default_features: false, + search_terms: &[Search::Positive("glow")], + }, ]; let mut any_failures = false; @@ -91,16 +183,25 @@ pub fn check_feature_dependencies(shell: Shell, arguments: Arguments) -> anyhow: log::debug!("{output}"); - for search_term in requirement.search_terms { + for (i, search_term) in requirement.search_terms.into_iter().enumerate() { + // Add a space and after to make sure we're getting a full match let found = match search_term { - Search::Positive(search_term) => output.contains(search_term), - Search::Negative(search_term) => !output.contains(search_term), + Search::Positive(search_term) => output.contains(&format!(" {search_term} ")), + Search::Negative(search_term) => !output.contains(&format!(" {search_term} ")), }; if found { - log::info!("✅ Passed!"); + log::info!( + "✅ Passed! ({} of {})", + i + 1, + requirement.search_terms.len() + ); } else { - log::info!("❌ Failed"); + log::info!( + "❌ Failed! ({} of {})", + i + 1, + requirement.search_terms.len() + ); any_failures = true; } }