Skip to content

Commit

Permalink
Prefer EGL over GLX
Browse files Browse the repository at this point in the history
should fix Nvidia proprietary driver issues on XWayland
  • Loading branch information
CasualPokePlayer committed Sep 4, 2024
1 parent 84de885 commit 60fae35
Showing 1 changed file with 66 additions and 6 deletions.
72 changes: 66 additions & 6 deletions src/BizHawk.Bizware.Graphics/OpenGL/SDL2OpenGLContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using Silk.NET.OpenGL;
#endif

using BizHawk.Common;

using static SDL2.SDL;

namespace BizHawk.Bizware.Graphics
Expand All @@ -16,16 +18,59 @@ public class SDL2OpenGLContext : IDisposable
{
static SDL2OpenGLContext()
{
if (OSTailoredCode.IsUnixHost)
{
// make sure that Linux uses the x11 video driver
// we need this as mono winforms uses x11
// and the user could potentially try to force the wayland video driver via env vars
SDL_SetHint("SDL_VIDEODRIVER", "x11");
// try to use EGL if it is available
// GLX is the old API, and is the more or less "deprecated" at this point, and potentially more buggy with some drivers
// we do need to a bit more work, in case EGL is not actually available or potentially doesn't have desktop GL support
SDL_SetHint(SDL_HINT_VIDEO_X11_FORCE_EGL, "1");

This comment has been minimized.

Copy link
@YoshiRulz

YoshiRulz Sep 9, 2024

Member

This commit broke the OpenGL display method for me. I'm not given a stacktrace, but removing this line

-SDL_SetHint(SDL_HINT_VIDEO_X11_FORCE_EGL, "1");

fixes it. edit: pushed 08bd14e

(Also, don't throw new(...), and definitely don't throw in a static ctor.)

This comment has been minimized.

Copy link
@CasualPokePlayer

CasualPokePlayer Sep 9, 2024

Author Member

The output/dll folder was actually updated when you pulled right? The previous commit updated our vendored SDL2 to actually support this.

This comment has been minimized.

Copy link
@YoshiRulz

YoshiRulz Sep 9, 2024

Member

Just tried deleting /output/dll and rebuilding, and building in Nix, and yes it's actually broken. There's a chance it's NixOS-specific.

This comment has been minimized.

Copy link
@CasualPokePlayer

CasualPokePlayer Sep 9, 2024

Author Member

What does MONO_LOG_LEVEL=debug MONO_LOG_MASK=dll log indicate?

This comment has been minimized.

Copy link
@YoshiRulz

YoshiRulz Sep 9, 2024

Member

Looks normal

[...]
Mono: DllImport attempting to load: 'SDL2'.
Mono: DllImport error loading library '/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/SDL2': '/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/SDL2: cannot open shared object file: No such file or directory'.
Mono: DllImport loaded library '/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so'.
Mono: DllImport searching in: 'SDL2' ('/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so').
Mono: Searching for 'SDL_SetHint'.
Mono: Probing 'SDL_SetHint'.
Mono: Found as 'SDL_SetHint'.
Mono: DllImport searching in: 'SDL2' ('/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so').
Mono: Searching for 'SDL_GL_MakeCurrent'.
Mono: Probing 'SDL_GL_MakeCurrent'.
Mono: Found as 'SDL_GL_MakeCurrent'.
Mono: DllImport searching in: 'SDL2' ('/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so').
Mono: Searching for 'SDL_GL_GetCurrentWindow'.
Mono: Probing 'SDL_GL_GetCurrentWindow'.
Mono: Found as 'SDL_GL_GetCurrentWindow'.
Mono: DllImport searching in: 'SDL2' ('/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so').
Mono: Searching for 'SDL_GL_GetCurrentContext'.
Mono: Probing 'SDL_GL_GetCurrentContext'.
Mono: Found as 'SDL_GL_GetCurrentContext'.
Mono: DllImport searching in: 'SDL2' ('/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so').
Mono: Searching for 'SDL_Init'.
Mono: Probing 'SDL_Init'.
Mono: Found as 'SDL_Init'.
Mono: DllImport searching in: 'SDL2' ('/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so').
Mono: Searching for 'SDL_GetError'.
Mono: Probing 'SDL_GetError'.
Mono: Found as 'SDL_GetError'.
Mono: DllImport searching in: 'SDL2' ('/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so').
Mono: Searching for 'SDL_GL_LoadLibrary'.
Mono: Probing 'SDL_GL_LoadLibrary'.
Mono: Found as 'SDL_GL_LoadLibrary'.
Mono: DllImport searching in: 'SDL2' ('/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so').
Mono: Searching for 'SDL_GL_ResetAttributes'.
Mono: Probing 'SDL_GL_ResetAttributes'.
Mono: Found as 'SDL_GL_ResetAttributes'.
Mono: DllImport searching in: 'SDL2' ('/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so').
Mono: Searching for 'SDL_GL_SetAttribute'.
Mono: Probing 'SDL_GL_SetAttribute'.
Mono: Found as 'SDL_GL_SetAttribute'.
Mono: DllImport searching in: 'SDL2' ('/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so').
Mono: Searching for 'SDL_CreateWindow'.
Mono: Probing 'SDL_CreateWindow'.
Mono: Found as 'SDL_CreateWindow'.
Mono: DllImport searching in: 'SDL2' ('/nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so').
Mono: Searching for 'SDL_free'.
Mono: Probing 'SDL_free'.
Mono: Found as 'SDL_free'.
[...]

This comment has been minimized.

Copy link
@CasualPokePlayer

CasualPokePlayer Sep 9, 2024

Author Member

I assume /nix/store/j8b30r7h6bm6pnyfqvzfxd8v47bpyak5-BizHawk-2.9.2-local/dll/libSDL2.so is supposed to be the vendored SDL2 and not some package manager SDL2, strange.

Could just do a NixOS check and just always force GLX in that case (why it doesn't work is ???)

EDIT: Double checking on my own machine (with Debian 11) and it works fine for me.

This comment has been minimized.

Copy link
@YoshiRulz

YoshiRulz Sep 9, 2024

Member

It might be not working because it's vendored. What changes did you make? If it's a compile flag or a patch, I can have Nix apply that to the "system" copy and it should run properly. Worst-case, I can remove the library from the output and have it use the system one with whatever the behaviour was that you didn't like.

This comment has been minimized.

Copy link
@CasualPokePlayer

CasualPokePlayer Sep 9, 2024

Author Member

libsdl-org/SDL#10645

https://github.com/TASEmulators/BizHawk/blob/master/ExternalProjects/SDL2/CMakeLists.txt

The original reason for vendoring in the first place was due to the usage of SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL, which is a relatively new hint I can't rely on the system SDL2 to have. Now, this PR would be another reason to use the vendored version.

I'm not sure why the vendored version would not work here anyways. The code would go back to GLX if EGL is completely non-functional (context creation fails for SDL window). If the PR is not applied you'd get jack anyways (context creation failure once it gets to trying to create one for a foreign window, due to lack of EGL surface creation for foreign windows).

To be clear, at what point is the code failing? Context creation failure? Some black screen?

This comment has been minimized.

Copy link
@YoshiRulz

YoshiRulz Sep 10, 2024

Member

Before the PresentationPanel is initialised; it's this error dialog

new ExceptionBox(new Exception($"Initialization of OpenGL Display Method failed; falling back to {name}")).ShowDialog();

so OpenGLVersion.SupportsVersion(3, 2) is returning false.

Unfortunately, it seems like removing the bundled copy of SDL2 doesn't help, not even if I apply https://patch-diff.githubusercontent.com/raw/libsdl-org/SDL/pull/10645.patch to the "system" copy.

This comment has been minimized.

Copy link
@CasualPokePlayer

CasualPokePlayer Sep 10, 2024

Author Member

That's super strange regardless. The EGL context test specifically tries to create an OpenGL 3.2 context. Although it does end up skipping checking the version string to make sure it is actually >=3.2, so perhaps the driver is doing something bad and not creating a compatible context? Could you check what version string is being returned?

var versionString = gl.GetStringS(StringName.Version);

This comment has been minimized.

Copy link
@YoshiRulz

YoshiRulz Sep 10, 2024

Member

At 08bd14e, 3.2.0 NVIDIA 550.78, correctly parsed as 3.2.

This comment has been minimized.

Copy link
@CasualPokePlayer

CasualPokePlayer Sep 10, 2024

Author Member

And before that commit?

This comment has been minimized.

Copy link
@YoshiRulz

YoshiRulz Sep 11, 2024

Member

Well between this commit and that one it crashes. At 84de885 (60fae3540^) it's the same though.

edit: moved to 3b62a38

}

// init SDL video
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
throw new($"Could not init SDL video! SDL Error: {SDL_GetError()}");
}

// load the default OpenGL library
if (SDL_GL_LoadLibrary(null) != 0)
if (OSTailoredCode.IsUnixHost)
{
// if we fail to load EGL, we'll just try again with GLX...
var loadGlx = SDL_GL_LoadLibrary(null) != 0;

if (!loadGlx)
{
try
{
// check if we can actually create a desktop GL context
using var glContext = new SDL2OpenGLContext(3, 2, true);
}
catch
{
// failed to create a context, fallback to GLX
loadGlx = true;
}
}

if (loadGlx)
{
SDL_SetHint(SDL_HINT_VIDEO_X11_FORCE_EGL, "0");
if (SDL_GL_LoadLibrary(null) != 0)
{
throw new($"Could not load default OpenGL library! SDL Error: {SDL_GetError()}");
}
}
}
else
{
throw new($"Could not load default OpenGL library! SDL Error: {SDL_GetError()}");
// load the default OpenGL library
if (SDL_GL_LoadLibrary(null) != 0)
{
throw new($"Could not load default OpenGL library! SDL Error: {SDL_GetError()}");
}
}

// we will be turning a foreign window into an SDL window
Expand Down Expand Up @@ -53,7 +98,6 @@ private static void SetAttributes(int majorVersion, int minorVersion, bool coreP
|| SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_GREEN_SIZE, 8) is not 0
|| SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_BLUE_SIZE, 8) is not 0
|| SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_ALPHA_SIZE, 0) is not 0
|| SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_DEPTH_SIZE, 24) is not 0
|| SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_DOUBLEBUFFER, 1) is not 0)
{
throw new($"Could not set GL attributes! SDL Error: {SDL_GetError()}");
Expand Down Expand Up @@ -122,7 +166,15 @@ public SDL2OpenGLContext(IntPtr nativeWindowhandle, int majorVersion, int minorV
throw new($"Could not create SDL Window! SDL Error: {SDL_GetError()}");
}

CreateContext();
try
{
CreateContext();
}
catch
{
Dispose();
throw;
}
}

public SDL2OpenGLContext(int majorVersion, int minorVersion, bool coreProfile)
Expand All @@ -138,7 +190,15 @@ public SDL2OpenGLContext(int majorVersion, int minorVersion, bool coreProfile)
throw new($"Could not create SDL Window! SDL Error: {SDL_GetError()}");
}

CreateContext();
try
{
CreateContext();
}
catch
{
Dispose();
throw;
}
}

public void Dispose()
Expand Down

0 comments on commit 60fae35

Please sign in to comment.