Fixing EGL Context Sharing, Windowless Buffers, BadDisplay #7965
alextechcc
started this conversation in
General
Replies: 1 comment
-
To make it clear, |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I've got two SoCs with proprietary drivers that seem impossible to run on Vulkan but show promise with opengl. Unfortunately they both cannot handle the current hacks for the context. I want to try to kick off fixing this but my background is absolutely not here. So, I think the best way forward is to try and summarize everything I could find on the issue and suggestions, as it sprawls several projects and issues and comments.
I plan to try and clean this up over time and suggest ways forward.
Big history and background
Suggestion to implement surfman: gfx-rs/gfx#3133
Seems a big reason that surfman was originally added was to get surfaces independent of a context.
... But then part of the implementation relied on luck
Originally posted by @zicklag in #3133
Decouple surfaces from GL contexts: servo/surfman#202
Surfman never really made this split correctly, but there was some suggestions on how to do it:
Originally posted by @kvark in #450
Proposal to drop surfman and use EGL directly: gfx-rs/gfx#3468
Then, surfman was decided to be dropped in favor of just using EGL, as it's purpose wasn't met and it was flaky.
"Is OpenGL Supported Now?" #450
Here there is some discussion about a "raw wayland context". I'm assuming here they mean a context not bound to a window. And how it may work to share resources between these.
Suggestion to use glutin to manage OpenGL contexts: #5643
Then, someone suggested bringing back glutin, but it seems that the idea was rejected somewhat.
Originally posted by @grovesNL in #5643
BadDisplay Issue: #5505
Then we realized that there's a problem with the fact that we have this temporary independent wl_display->EGLDisplay used to query being the initial context. It seems that this temporary context got used for too much, and then got hacked around and leaked in a way that seems to have unsound behavior impossible to fix. I think that it's because when you hand it an external context, it can't share it, so it has to current/uncurrent it in a way that it can't prove is safe. I think this is probably a wrong interpretation...
This was posted as a possible way we could do this. Let WGPU live in its own independent windowless world and use DMA-BUF to share the rendered texture with the other completely independent world - so that the wl_display/context sharing all doesn't matter. But this then means you can't render direct- I'd assume.
Then, some good background and maybe some advice for looking into glutin:
Then a potential issue was brought up with the general strategy of making a temporary set of displays/contexts, and swapping them out when you get a surface.
Then some more info on a strategy for sharing contexts.
Originally posted by @MarijnS95 in #5505
Then, somewhat of a go-ahead to start ripping out egl.rs and replacing with glutin:
Originally posted by @MarijnS95 in #6289
A bit of a design with trying to get the display handle into the adapter.
I believe this is talking about a world where we force users to go down a purely linear path to make the APIs happy and all agree on the contexts/displays. But that you currently can set up an adapter without any regard for the surface you'd use it on and share the adapter between surfaces.
Originally posted by @cwfitzgerald in #5505
Current hack to get AM62 GPU GL working
The re-init hack when creating a surface:
#[cfg(not(Emscripten))]
(Rwh::Wayland(_), raw_window_handle::RawDisplayHandle::Wayland(display_handle)) => {
if inner
.wl_display
.map(|ptr| ptr != display_handle.display.as_ptr())
.unwrap_or(true)
{
/* Wayland displays are not sharable between surfaces so if the
* surface we receive from this handle is from a different
* display, we must re-initialize the context.
*
* See gfx-rs/gfx#3545
*/
log::warn!("Re-initializing Gles context due to Wayland window");
use std::ops::DerefMut;
let display_attributes = [khronos_egl::ATTRIB_NONE];
let display = unsafe {
inner
.egl
.instance
.upcast::<khronos_egl::EGL1_5>()
.unwrap()
.get_platform_display(
EGL_PLATFORM_WAYLAND_KHR,
display_handle.display.as_ptr(),
&display_attributes,
)
}
.unwrap();
let new_inner = Inner::create(
self.flags,
Arc::clone(&inner.egl.instance),
display,
inner.force_gles_minor_version,
)?;
let old_inner = std::mem::replace(inner.deref_mut(), new_inner);
inner.wl_display = Some(display_handle.display.as_ptr());
drop(old_inner);
}
}
wgpu/wgpu-hal/src/gles/egl.rs
Lines 935 to 979 in 6f16ea4
This hack makes it not usable for me on the AM62 SoC GPU, I haven't tracked down exactly what part of the context is leaked but I can get it running by:
DEFAULT_DISPLAY
herewgpu/wgpu-hal/src/gles/egl.rs
Line 802 in 6f16ea4
wgpu/wgpu-hal/src/gles/egl.rs
Line 656 in 6f16ea4
Current state
egl.rs
stuff withglutin
.glutin
may simplify or solve:wl_display*
matching though).BadDisplay
/DEFAULT_DISPLAY
is fixed by providing somewl_display
when gettingeglGetPlatformDisplay
, but this is not sufficient to prevent crashing as something is leaked or some context does not match up, causing it to crash when you start using the context after reinitializing from thewinit
wl_display*
.wl_display
up works with my ugly hack.Solutions?
1. Separate contexts, share resource to bridge the
wl_display
gapwl_display*
and related contexts independent betweenwinit
andwgpu
,wgpu
did onto the window.glutin
does any of this for us - unlikely?2. Change API to first require a surface
3. Fix the current hacks.
wl_display*
, and then use that to reinitialize what is needed.4. Use compatible surface when enumerating adapters.
Beta Was this translation helpful? Give feedback.
All reactions