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

Make all backends controlled by features (using a very ugly workaround) #6949

Draft
wants to merge 5 commits into
base: trunk
Choose a base branch
from

Conversation

Wumpf
Copy link
Member

@Wumpf Wumpf commented Jan 19, 2025

Connections

Description
Feature flag changes:

  • new vulkan feature for enabling Vulkan on Windows/Android/Linux (part of default feature set)
  • new gles feature for enabling Vulkan on Windows/Android/Linux (part of default feature set, debatable if that's a good idea)
  • fix webgl enabling GL on all platforms

This is achieved by introducing three proxy crates. Each depends on wgpu-core under a different platform condition and will "forward" all feature flags to it.

Reminder why this horrible construct is the only way:
This is necessary because it's impossible today to drag in a dependency conditionally BOTH on a platform & a feature flag.
It is possible to do all these things in code, so we can forward features all the way to wgpu-hal and not have it compile e.g. it's vulkan backend on Mac iff vulkan-portability is off. But without this workaround it's impossible to avoid building vulkan associated dependencies anyways.
For more details see

Building with default-features=false will now not even drag in wgpu-core! cargo tree -p wgpu --edges normal for simple application depending on wgpu this way:

wgpu v24.0.0 (D:\dev\wgpu\wgpu)
├── arrayvec v0.7.6
├── bitflags v2.8.0
│   └── serde v1.0.217
├── document-features v0.2.10 (proc-macro)
│   └── litrs v0.4.1
├── log v0.4.25
├── parking_lot v0.12.3
│   ├── lock_api v0.4.12
│   │   └── scopeguard v1.2.0
│   └── parking_lot_core v0.9.10
│       ├── cfg-if v1.0.0
│       ├── smallvec v1.13.2
│       └── windows-targets v0.52.6
│           └── windows_x86_64_msvc v0.52.6
├── profiling v1.0.16
├── raw-window-handle v0.6.2
├── smallvec v1.13.2
├── static_assertions v1.1.0
└── wgpu-types v24.0.0 (D:\dev\wgpu\wgpu-types)
    ├── bitflags v2.8.0 (*)
    └── log v0.4.25

Similarly, only depending on dx12 (on Windows) doesn't include ash or glow (the former is a slow building dependency!):

wgpu v24.0.0 (D:\dev\wgpu\wgpu)
├── arrayvec v0.7.6
├── bitflags v2.8.0
│   └── serde v1.0.217
├── document-features v0.2.10 (proc-macro)
│   └── litrs v0.4.1
├── log v0.4.25
├── parking_lot v0.12.3
│   ├── lock_api v0.4.12
│   │   └── scopeguard v1.2.0
│   └── parking_lot_core v0.9.10
│       ├── cfg-if v1.0.0
│       ├── smallvec v1.13.2
│       └── windows-targets v0.52.6
│           └── windows_x86_64_msvc v0.52.6
├── profiling v1.0.16
├── raw-window-handle v0.6.2
├── smallvec v1.13.2
├── static_assertions v1.1.0
├── wgpu-core v24.0.0 (D:\dev\wgpu\wgpu-core)
│   ├── arrayvec v0.7.6
│   ├── bit-vec v0.8.0
│   ├── bitflags v2.8.0 (*)
│   ├── document-features v0.2.10 (proc-macro) (*)
│   ├── hashbrown v0.15.2
│   │   └── foldhash v0.1.4
│   ├── indexmap v2.7.0
│   │   ├── equivalent v1.0.1
│   │   └── hashbrown v0.15.2 (*)
│   ├── log v0.4.25
│   ├── naga v24.0.0 (D:\dev\wgpu\naga)
│   │   ├── arrayvec v0.7.6
│   │   ├── bit-set v0.8.0
│   │   │   └── bit-vec v0.8.0
│   │   ├── bitflags v2.8.0 (*)
│   │   ├── codespan-reporting v0.11.1
│   │   │   ├── termcolor v1.4.1
│   │   │   │   └── winapi-util v0.1.9
│   │   │   │       └── windows-sys v0.59.0
│   │   │   │           └── windows-targets v0.52.6 (*)
│   │   │   └── unicode-width v0.1.14
│   │   ├── hexf-parse v0.2.1
│   │   ├── indexmap v2.7.0 (*)
│   │   ├── log v0.4.25
│   │   ├── rustc-hash v1.1.0
│   │   ├── strum v0.26.3
│   │   │   └── strum_macros v0.26.4 (proc-macro)
│   │   │       ├── heck v0.5.0
│   │   │       ├── proc-macro2 v1.0.93
│   │   │       │   └── unicode-ident v1.0.14
│   │   │       ├── quote v1.0.38
│   │   │       │   └── proc-macro2 v1.0.93 (*)
│   │   │       ├── rustversion v1.0.19 (proc-macro)
│   │   │       └── syn v2.0.96
│   │   │           ├── proc-macro2 v1.0.93 (*)
│   │   │           ├── quote v1.0.38 (*)
│   │   │           └── unicode-ident v1.0.14
│   │   ├── termcolor v1.4.1 (*)
│   │   ├── thiserror v2.0.11
│   │   │   └── thiserror-impl v2.0.11 (proc-macro)
│   │   │       ├── proc-macro2 v1.0.93 (*)
│   │   │       ├── quote v1.0.38 (*)
│   │   │       └── syn v2.0.96 (*)
│   │   └── unicode-xid v0.2.6
│   ├── once_cell v1.20.2
│   ├── parking_lot v0.12.3 (*)
│   ├── profiling v1.0.16
│   ├── raw-window-handle v0.6.2
│   ├── rustc-hash v1.1.0
│   ├── smallvec v1.13.2
│   ├── thiserror v2.0.11 (*)
│   ├── wgpu-hal v24.0.0 (D:\dev\wgpu\wgpu-hal)
│   │   ├── arrayvec v0.7.6
│   │   ├── bit-set v0.8.0 (*)
│   │   ├── bitflags v2.8.0 (*)
│   │   ├── gpu-allocator v0.27.0
│   │   │   ├── log v0.4.25
│   │   │   ├── presser v0.3.1
│   │   │   ├── thiserror v1.0.69
│   │   │   │   └── thiserror-impl v1.0.69 (proc-macro)
│   │   │   │       ├── proc-macro2 v1.0.93 (*)
│   │   │   │       ├── quote v1.0.38 (*)
│   │   │   │       └── syn v2.0.96 (*)
│   │   │   └── windows v0.58.0
│   │   │       ├── windows-core v0.58.0
│   │   │       │   ├── windows-implement v0.58.0 (proc-macro)
│   │   │       │   │   ├── proc-macro2 v1.0.93 (*)
│   │   │       │   │   ├── quote v1.0.38 (*)
│   │   │       │   │   └── syn v2.0.96 (*)
│   │   │       │   ├── windows-interface v0.58.0 (proc-macro)
│   │   │       │   │   ├── proc-macro2 v1.0.93 (*)
│   │   │       │   │   ├── quote v1.0.38 (*)
│   │   │       │   │   └── syn v2.0.96 (*)
│   │   │       │   ├── windows-result v0.2.0
│   │   │       │   │   └── windows-targets v0.52.6 (*)
│   │   │       │   ├── windows-strings v0.1.0
│   │   │       │   │   ├── windows-result v0.2.0 (*)
│   │   │       │   │   └── windows-targets v0.52.6 (*)
│   │   │       │   └── windows-targets v0.52.6 (*)
│   │   │       └── windows-targets v0.52.6 (*)
│   │   ├── hashbrown v0.15.2 (*)
│   │   ├── libloading v0.8.6
│   │   │   └── windows-targets v0.52.6 (*)
│   │   ├── log v0.4.25
│   │   ├── naga v24.0.0 (D:\dev\wgpu\naga) (*)
│   │   ├── once_cell v1.20.2
│   │   ├── parking_lot v0.12.3 (*)
│   │   ├── profiling v1.0.16
│   │   ├── range-alloc v0.1.4
│   │   ├── raw-window-handle v0.6.2
│   │   ├── rustc-hash v1.1.0
│   │   ├── thiserror v2.0.11 (*)
│   │   ├── wgpu-types v24.0.0 (D:\dev\wgpu\wgpu-types)
│   │   │   ├── bitflags v2.8.0 (*)
│   │   │   └── log v0.4.25
│   │   ├── windows v0.58.0 (*)
│   │   └── windows-core v0.58.0 (*)
│   └── wgpu-types v24.0.0 (D:\dev\wgpu\wgpu-types) (*)
└── wgpu-types v24.0.0 (D:\dev\wgpu\wgpu-types) (*)

Testing

  • separate test app with various config options
    • TODO: try some more

Checklist

  • Run cargo fmt.
  • Run taplo format.
  • Run cargo clippy. If applicable, add:
    • --target wasm32-unknown-unknown
    • --target wasm32-unknown-emscripten
  • Run cargo xtask test to run tests.
  • Add change to CHANGELOG.md. See simple instructions inside file.

Draft todo:

  • do we even want this abomination
  • fix lotsa unused warnings
  • document proxy crates
  • should GL really be in the default feature set
  • test this on Mac & Linux by hand
  • check on emscripten and other corner cases
  • surely ci fails ;-)
  • write changelog

@Wumpf Wumpf changed the title Make all backends controlled by features Make all backends controlled by features (using a very very very ugly workaround) Jan 19, 2025
Copy link
Member

@cwfitzgerald cwfitzgerald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is broadly fine, I will have some comments on specifics once this is ready for review, but we definitely shouldn't be scared of crates. Might be worthwhile looking into cargo-release or release-plz or something if the count grows.

@sagudev
Copy link
Contributor

sagudev commented Jan 19, 2025

Building with default-features=false will now not even drag in wgpu-core! cargo tree -p wgpu --edges normal for simple application depending on wgpu this way

This is important for #6330, I even impl it as faafd37.

@Wumpf Wumpf changed the title Make all backends controlled by features (using a very very very ugly workaround) Make all backends controlled by features (using a very ugly workaround) Jan 19, 2025
Copy link
Contributor

@brody4hire brody4hire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick comments from an outsider

Comment on lines 22 to +25
"wgpu",
"wgpu-core-target-feature-conditionals/arch-wasm32",
"wgpu-core-target-feature-conditionals/native-non-apple",
"wgpu-core-target-feature-conditionals/vendor-apple",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we consider shorter names for these, perhaps with slight reordering?

Suggested change
"wgpu",
"wgpu-core-target-feature-conditionals/arch-wasm32",
"wgpu-core-target-feature-conditionals/native-non-apple",
"wgpu-core-target-feature-conditionals/vendor-apple",
"wgpu-core-target-features/arch-wasm32",
"wgpu-core-target-features/native-non-apple",
"wgpu-core-target-features/vendor-apple",
"wgpu",

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah those names are definitely too crazy right now

Comment on lines -69 to -99

if cfg!(native) {
if cfg!(metal) {
backends = backends.union(Backends::METAL);
}
if cfg!(dx12) {
backends = backends.union(Backends::DX12);
}

// Windows, Android, Linux currently always enable Vulkan and OpenGL.
// See <https://github.com/gfx-rs/wgpu/issues/3514>
if cfg!(target_os = "windows") || cfg!(unix) {
backends = backends.union(Backends::VULKAN).union(Backends::GL);
}

// Vulkan on Mac/iOS is only available through vulkan-portability.
if cfg!(target_vendor = "apple") && cfg!(feature = "vulkan-portability") {
backends = backends.union(Backends::VULKAN);
}

// GL on Mac is only available through angle.
if cfg!(target_os = "macos") && cfg!(feature = "angle") {
backends = backends.union(Backends::GL);
}
} else {
if cfg!(webgpu) {
backends = backends.union(Backends::BROWSER_WEBGPU);
}
if cfg!(webgl) {
backends = backends.union(Backends::GL);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<3 always love for removing large blocks of ugly code :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a default feature for wgpu that enables Vulkan & GLES on Windows & Linux
4 participants