Skip to content

Allow optional RawDisplayHandle in InstanceDescriptor #8012

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

Draft
wants to merge 1 commit into
base: trunk
Choose a base branch
from

Conversation

MarijnS95
Copy link
Contributor

@MarijnS95 MarijnS95 commented Jul 26, 2025

Connections
Probably supersedes #7969
Fixes #5505
Fixes #3176
Fixes #7965

Description
This allows platforms like GLES with EGL context backend to properly initialize such that their EGLDisplay and EGLContext are compatible with an incoming Surface, which is otherwise impossible if not for hotpatching the context (and loosing all resources created on it) when a surface comes in and that compositor connection becomes known.

This hotpatching is known to break quite a few systems and initialization ordering (i.e. the alternative is forcing users to create surfaces before querying adapters, which isn't feasible on platform like Android), and is better avoided or at least made possible by using the (Raw)DisplayHandle abstraction provided by raw_display_handle in the way it's intended to be used (additionally, removing it from the surface would be a sensible decision). This was suggested long ago in #6211 (comment).

There may however be cases where users want to initialize multiple Instances or perhaps Adapters for independent RawDisplayHandles, and certain backends may be designed specifically to cope with this (i.e. Vulkan).

Note that this PR does nothing to address many other soundness problems inside the EGL backend.

Testing
Using a Wayland compositor with:

WGPU_BACKEND=gl cargo r -p wgpu-examples -- shadow

Squash or Rebase?
rebase

Checklist

  • Run cargo fmt.
  • Run taplo format.
  • Run cargo clippy --tests. If applicable, add:
    • --target wasm32-unknown-unknown
  • Run cargo xtask test to run tests.
  • If this contains user-facing changes, add a CHANGELOG.md entry.

@alextechcc
Copy link

alextechcc commented Jul 27, 2025

Wow this cleans up a ton of code. Wonderful!

Have you thought about putting the display connection into GlBackendOptions? https://github.com/gfx-rs/wgpu/blob/trunk/wgpu-types/src/instance.rs#L321

Obviously it's already been mentioned that the vulkan backend could benefit from this, though that means we could also chuck the parameter in that struct too if we're being selective. Just thinking of minimizing the blast radius of these changes. As it stands, I think anyone who constructs an InstanceDescriptor has the "breaking change" with this PR that they need to specify something for display. Not sure how breaking changes are handled with wgpu.

I haven't had much time to work on this for a while, but I'm planning to try this with bevy at some point.

EDIT: I got bevy working with this PR. I'm not sure if I'm stepping on any toes here but bevy has its winit crate depend on the crate doing wgpu stuff, so it feels pretty wonky - but I can move around the types such that I have access to the display handle immediately and pass it to the instance descriptor. It seems there's a good amount of thread safety related stuff I have to read through, and if I want to make GL a viable option again I probably should make this a little less annoying: bevyengine/bevy#18932 and this bevyengine/bevy#13115

This allows platforms like GLES with EGL context backend to properly
initialize such that their `EGLDisplay` and `EGLContext` are compatible
with an incoming `Surface`, which is otherwise impossible if not for
hotpatching the context (and loosing all resources created on it) when a
surface comes in and that compositor connection becomes known.

This hotpatching is known to break quite a few systems and
initialization ordering (i.e. the alternative is forcing users to create
surfaces before querying adapters, which isn't feasible on platform like
Android), and is better avoided or at least made possible by using the
`(Raw)DisplayHandle` abstraction provided by `raw_display_handle` in the
way it's intended to be used (additionally, removing it from the surface
would be a sensible decision).

There may however be cases where users want to initialize multiple
`Instance`s or perhaps `Adapter`s for independent `RawDisplayHandle`s,
and certain backends may be designed specifically to cope with this
(i.e. Vulkan).

Note that this PR does nothing to address many other soundness problems
inside the EGL backend.
@MarijnS95 MarijnS95 force-pushed the instance-for-raw-display-handle branch from 21320be to eb8afd5 Compare July 31, 2025 21:32
MarijnS95 added a commit to MarijnS95/bevy that referenced this pull request Jul 31, 2025
…tance` creation

Multiple community members have asked me to look into persistent
`BadDisplay` crashes on `wgpu` when using its EGL backend in
conjunction with Wayland.  Besides realizing that this backend is
quite literally the definition of Undefined Behaviour itself, various
hacks to patch the EGL context - which is compositor-specific - inside
the `Instance`/`Adapter` with the actual `wl_display` handle as soon
as a `surface` is created will not only void any previously created
GL resources, only the `Instance` handles are patched leaving any
previously queried `Adapter`s to reference destroyed EGL objects causing
those `BadDisplay` errors.

Solving that handle lifetime/ownership problem has yet to be done
(and is why crates like `glutin` exist...), but at the very least
we might as well create an `EGLDisplay` and `EGLContext` which is
compatible with the current compositor from the get-go, which is
what gfx-rs/wgpu#8012 allows callers to
do.  This is one of the reasons why `raw-display-handle` split out
a `RawDisplayHandle` type and related enums: to know up-front what
compositor is used (telling X11 and Wayland apart, if both could be
used concurrently instead of letting `wgpu` "guess") and to use the same
`wl_display` compositor connection as `winit`.

There are alternatives available, which is why this and the related
`wgpu` PR is a draft to shake out some feedback.  Anything that's
involving more complexity inside `wgpu`'s EGL backend should be
attempted incredibly cautiously if it weren't for a full rewrite on top
of a higher-level EGL abstraction.
MarijnS95 added a commit to MarijnS95/bevy that referenced this pull request Aug 6, 2025
…tance` creation

Multiple community members have asked me to look into persistent
`BadDisplay` crashes on `wgpu` when using its EGL backend in
conjunction with Wayland.  Besides realizing that this backend is
quite literally the definition of Undefined Behaviour itself, various
hacks to patch the EGL context - which is compositor-specific - inside
the `Instance`/`Adapter` with the actual `wl_display` handle as soon
as a `surface` is created will not only void any previously created
GL resources, only the `Instance` handles are patched leaving any
previously queried `Adapter`s to reference destroyed EGL objects causing
those `BadDisplay` errors.

Solving that handle lifetime/ownership problem has yet to be done
(and is why crates like `glutin` exist...), but at the very least
we might as well create an `EGLDisplay` and `EGLContext` which is
compatible with the current compositor from the get-go, which is
what gfx-rs/wgpu#8012 allows callers to
do.  This is one of the reasons why `raw-display-handle` split out
a `RawDisplayHandle` type and related enums: to know up-front what
compositor is used (telling X11 and Wayland apart, if both could be
used concurrently instead of letting `wgpu` "guess") and to use the same
`wl_display` compositor connection as `winit`.

There are alternatives available, which is why this and the related
`wgpu` PR is a draft to shake out some feedback.  Anything that's
involving more complexity inside `wgpu`'s EGL backend should be
attempted incredibly cautiously if it weren't for a full rewrite on top
of a higher-level EGL abstraction.
MarijnS95 added a commit to MarijnS95/bevy that referenced this pull request Aug 8, 2025
…tance` creation

Multiple community members have asked me to look into persistent
`BadDisplay` crashes on `wgpu` when using its EGL backend in
conjunction with Wayland.  Besides realizing that this backend is
quite literally the definition of Undefined Behaviour itself, various
hacks to patch the EGL context - which is compositor-specific - inside
the `Instance`/`Adapter` with the actual `wl_display` handle as soon
as a `surface` is created will not only void any previously created
GL resources, only the `Instance` handles are patched leaving any
previously queried `Adapter`s to reference destroyed EGL objects causing
those `BadDisplay` errors.

Solving that handle lifetime/ownership problem has yet to be done
(and is why crates like `glutin` exist...), but at the very least
we might as well create an `EGLDisplay` and `EGLContext` which is
compatible with the current compositor from the get-go, which is
what gfx-rs/wgpu#8012 allows callers to
do.  This is one of the reasons why `raw-display-handle` split out
a `RawDisplayHandle` type and related enums: to know up-front what
compositor is used (telling X11 and Wayland apart, if both could be
used concurrently instead of letting `wgpu` "guess") and to use the same
`wl_display` compositor connection as `winit`.

There are alternatives available, which is why this and the related
`wgpu` PR is a draft to shake out some feedback.  Anything that's
involving more complexity inside `wgpu`'s EGL backend should be
attempted incredibly cautiously if it weren't for a full rewrite on top
of a higher-level EGL abstraction.
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.

EGL BadDisplay when using Wayland No EGL_DEFAULT_DISPLAY on GL Backend + Wayland (Vivante/OpenGL2)
2 participants