Handle Multi-threaded EGL Context Access#1729
Conversation
cwfitzgerald
left a comment
There was a problem hiding this comment.
I mean, I hate it, but seems mostly reasonable. I want to test this on stuff like rpi and android to see if it works.
5a45663 to
5a21494
Compare
Yeah, according to the EGL spec we can't access the context in multiple threads at a time so essentially we're stuck. 🤷♂️ Oh, something I forgot. I don't know how to test it, but according to the EGL spec I think the dummy We may need to try to detect that and maybe add a downlevel flag or an error message or something. Edit: We may also want to create a multi-threaded example sometime. Currently my only test-case for this is a fork of Bevy updated for WGPU on master. |
|
We already do have a multithreaded example, it's Would having thread-local pbuffers work? I tested this PR on my intel/haswell machine using the GL tests, and got tons of errors: |
|
The shader translation error is probably due to gfx-rs/naga#1137. |
kvark
left a comment
There was a problem hiding this comment.
I like this approach quite a bit.
Previously in gfx, we had a wrapper around GL content that would just make it current without any locks. It was quite painful.
Here, we are locking the context and guaranteeing safe access.
5a21494 to
e47c43a
Compare
I think so.
Does that machine support surfaceless EGL? If it doesn't, then it's probably the pbfuffer problem. I'll try out thread local pbuffers and then you could test it to see if that fixes it.
That one fails on master with the expected "DeviceLost" that you get when creating a buffer on a different thread. It still fails with this PR, but with a different message. Not sure why: |
It definitely should considering it's running on mesa. Is there a particular extension I should be looking out for?
We had a test that used to fail on vulkan but now succeeds but we never marked the test to pass. #1731 fixed it. |
e47c43a to
00d1c17
Compare
For some reason the test still fails after rebasing. |
|
Oh I misread what was causing it. This is because it now passes on your machine but is still marked to fail on OpenGL. You should got to the test definition
Yeah this doesn't support that, it only supports EGL 1.4. In fact all my GL devices are only EGL 1.4. That being said, it does support |
Ah, I get it now. 👍
Well if it supports the extension then we shouldn't have a problem. Are you not seeing the Lines 331 to 343 in 9ce884c
That fixed it. Now all the Bevy examples work! |
00d1c17 to
675592f
Compare
|
Yeah the check is wrong. that should be && not ||. |
|
Oh, duh. 🤦♂️ Well, it looks like we found a way to test the pbuffer workaround. :) I'll fix that check and push an update, then it should work for you on your EGL 1.4 devices. Then I'll also experiment to see if I can get the pbuffer workaround working by adding |
f4db755 to
af23509
Compare
|
OK I fixed the surfaceless check and I also fixed the error you were getting earlier with "Got an EGLSurface but no EGLContext". When I made the context not current I was not supposed to bind the pbuffer as the current surface. Also the pbuffer workaround works totally fine with multi-threading so we won't need thread-local pbuffers or anything. I was misinterpreting when we would need to bind the pbuffer. Since we only bind the pbuffer when we bind the context, everything is fine and it is only ever bound by one thread. If this works on your hardware @cwfitzgerald, I think this should be ready ( pending re-review ). |
Implements the synchronization necessary to use the GL backend from multiple threads.
af23509 to
671e393
Compare
|
Pushed an update! |
|
Alright, so all tests pass as long as I pass in |
Interesting. All the tests pass for me, even without the
👍 |
|
uh, isn't this a bit worrying? The whole point of the PR is to support more than one thread. |
It does, the multi-threaded example works perfectly fine, it's juggling multiple adapters which is the issue (which is what the test harness is doing without --test-threads=1). So I'm comfortable trying to deal with this in a follow up.
Yeah ofc! |
|
ok, sounds reasonable |
|
Build succeeded: |
|
Awesome! Thanks guys! I'm super excited to actually have gotten Bevy running on OpenGL. 😃 |
|
Thank you for all the help getting it working! |

Connections
#1630, bevyengine/bevy#841
Description
Implements the synchronization necessary to use the GL backend from multiple threads. Accomplishes this by using a mutex around the GL context with extra wrapping to bind and unbind the EGL context when locking and unlocking.
Testing
Tested on Ubunty 20.04 with a fork of the Bevy game engine and the WGPU examples ( not that the examples test the multi-threading ).
Remaining Issues
There is only one Bevy example I cannot get to run yet and it's the
load_gltfexample. It fails with a shader translation error:Interestingly, I think the shader in question doesn't have a
group(3), binding(10)anywhere that I know of so I'm going to have to drill down a bit more and find out exactly which shader translation is failing more.This could potentially be fixed in a separate PR. I think the rest of this PR is rather straight-forward and the fix for the error above is probably mostly unrelated to the primary changes made in this PR.