Open teoxoy opened 1 year ago
I was recently looking into this but the first roadblock I hit is that we can't differentiate between a new gles
crate feature and the current angle
crate feature, both enable wgc/gles
.
A solution could be to introduce target-specific features in wgpu-core
and wgpu-hal
that are no-op on certain platforms.
E.g. gles-native
(no-op on MacOS) and gles-angle
(no-op on everything but MacOS). This proposal would be similar to https://github.com/gfx-rs/wgpu/pull/3466.
I'd be happy to make a PR!
I think we're moving in the direction of every backend being feature flagged. We have all the infrastructure in place, we just haven't lifted this to the wgpu level.
Distinguishing between angle and native would be useful!
So after playing around with it a bit I was so unsatisfied it doesn't make sense to me to proceed like that. The issue basically boils down to Cargo not being able to connect crate features that activate optional dependencies to specific targets.
Introducing gles-native
and gles-angle
we can use cfg
s to guard code to specific targets, but the dependencies these features activate will be active nevertheless. E.g. if we use default = ["gles-native"]
, OpenGL won't work on MacOS, but the dependencies will still be present.
So the only good solution I can come up with to this problem is to create a separate crate that adds these defaults.
[package]
name = "wgpu-default-features"
# We want the wgpu-core Metal backend on macOS and iOS.
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgc]
workspace = true
features = ["metal"]
# We want the wgpu-core Direct3D backends and OpenGL (via WGL) on Windows.
[target.'cfg(windows)'.dependencies.wgc]
workspace = true
features = ["dx11", "dx12", "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]
workspace = true
features = ["vulkan"]
# We want the wgpu-core GLES backend on Unix (but not macOS, iOS).
[target.'cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))'.dependencies.wgc]
workspace = true
features = ["gles"]
And then we can use default ["dep:wgpu-default-features"]
in wgpu
.
Just for completeness, not actually proposing this: we could abandon default features.
Cc https://github.com/rust-lang/cargo/issues/1197. Left a user story there as well.
cont' conversation thread from https://github.com/gfx-rs/wgpu/pull/4815#issuecomment-1837096793
to quickly recap (plz correct me if needed): I suggested going all in on a style like gles-linux
, gles-windows
, gles-mac
which is then translated to just gles
in the code via https://docs.rs/cfg_aliases/latest/cfg_aliases/
As @daxpedda points out (and described here already!) this doesn't quite work since for instance gles-linux = ["wgc/gles"]
would drag inwgc/gles
for on Mac no matter what.
It's pretty awful, but it might be better than the alternative to just hand this problem on to wgc in turn? I.e. gles-linux = ["wgc/gles-linux"]
. It seems to me that this is the least invasive situation and gives the same feature (literally) to the few direct users for wgpu-core where the problem would bubble up otherwise in the exact same way.
It's pretty awful, but it might be better than the alternative to just hand this problem on to wgc in turn?
We would have to go further into hal though, because in wgc we are having the exact same problem: gles-linux = ["hal/gles"]
. Looking at hal, the gles
feature activates the following dependencies:
naga/glsl-out
glow
glutin_wgl_sys
khronos-egl
libloading
Both naga/glsl-out
and glow
are not target specific dependencies, so we would be hitting the same problem again in hal as well: enabling hal/gles-linux
would still bring in these dependencies no matter the target.
Why is it an issue that the dependencies will be present on the dev machine? They won't be compiled for the targets that don't support them.
Introducing
gles-native
andgles-angle
we can usecfg
s to guard code to specific targets, but the dependencies these features activate will be active nevertheless.
What does "active" mean in this context?
Why is it an issue that the dependencies will be present on the dev machine? They won't be compiled for the targets that don't support them.
Dead code elimination is not perfect, especially with things that rely on FFI and linked libraries, I don't have any data on that though. But it also does increase compile time, which is not insignificant when looking at the size and amount of dependencies we are talking about here.
E.g. I know it was reported somewhere that MoltenVK is a problem because of linking, which is why it was removed from the default set in wgpu
.
Introducing
gles-native
andgles-angle
we can usecfg
s to guard code to specific targets, but the dependencies these features activate will be active nevertheless.What does "active" mean in this context?
I should probably stick with the word "enable". It means that a feature that enables a dependency pulls it in, it becomes part of the dependency graph and has to be compiled and such.
Note that this currently prevents the usage of pipeline-overridable constants on linux, since these don't seem to be supported on glsl-out.
Unsure if they will ever be supported on that backend, if not then I'd say this gains another strong reason to happen.
@9SMTM6 that's a completely orthogonal issue and not a known one I think: Pipeline overridable constants should work everywhere just fine starting with wgpu 0.20.0. Please open a new issue, ideally with a code snippet reproducing the problem. This issue here is about having no easy opt out of the GLES backend when it's unwanted
@Wumpf I have just realized that too, since I've gotten around to patching out the glsl backend.
Sorry for that, it made sense to me at that point, but evidently my pipeline is too complex for me to be able to properly attribute reason. I did check whether I only had wgpu 20.1+ with cargo tree, but as I said, with the glsl backend patched out it still doesn't work. And the way the error surfaced did not really make sense.
At this point I think the issue lies with naga_oil, I found part of the verbiage there, but I'll have to test more before I make a issue out of that ;-P.
We currently only enable backends based on the target platform with the only exception being GLES which is always available.
We should expose a new feature flag (enabled by default) that covers the GLES and DX11 backends so that users not interested in those backends can avoid compiling them in their binaries.
Feature name ideas:
legacy
compat
(mapping to a future WebGPU Compat; might not be the best choice since we support even lower limits/features than what WebGPU Compat is aiming for; i.e. GLES 3.1+ and DX11 FL10+)See background for this: https://github.com/gfx-rs/wgpu/issues/1221#issuecomment-1430067962