CaffeineMC / sodium

A Minecraft mod designed to improve frame rates and reduce micro-stutter
Other
4.81k stars 812 forks source link

Allow Minecraft to detect & use native Wayland compositor on Linux #1481

Closed gianni-rosato closed 10 months ago

gianni-rosato commented 2 years ago

Problem: When launching the game with fractional scaling enabled at 1.5x on my display, the game runs at lower resolution. I am on the Framework Laptop & my display is 2256x1504 but the game will run at 1503x1002. This is because Minecraft runs on XWayland, & X11 doesn't support fractional scaling.

Solution: Since LWJGL 3.3.0, the lwjgl GLFW natives are unified for both X11 and Wayland & there is only one binary. The game needs to give a hint to lwjgl that it would like to use Wayland.

glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND)

Minecraft can also detect if wayland is available with:

glfwPlatformSupported(GLFW_PLATFORM_WAYLAND)

Minecraft 1.19+ use LWJGL 3.3.1 so have native support for this. Mojang just needs to add that detection and hint and you are done. I could see a very simple implementation being done in Sodium to provide this detection & allow the game to run natively on Wayland.

Alternatives: Either GNOME fixes X11’s problems with fractional scaling, Mojave implements this themselves, or another person makes this change to their mod to provide the detection necessary. Maybe Iris or something. So far, going through Sodium seemed like the best idea because of the goal to modernize Minecraft’s OpenGL stack.

if you would like to replicate: Set display scaling to 1.25x or another fractional scaling increment on Gnome (I'm sure KDE as well) Set up & launch Minecraft Fullscreen the game Press F3 Cross-reference game resolution with your display's native resolution

jellysquid3 commented 2 years ago

It doesn't seem to fix fractional scaling for me. For example, on KDE Plasma with a 3840x2160 display using 150% scaling, the game uses a resolution of 5120x2880 in full screen (two times the size of the virtual coordinate space of 2560x1440), which is nearly 80% more physical pixels the game needs to render before the compositor decides to scale it back down.

While the downscaling that causes looks a lot better than upscaling, the performance cost is immense, and it almost halves the frame rate on my system.

jellysquid3 commented 2 years ago

Some other observations:

And from what I know about trying to replace the GLFW library with newer versions:

jellysquid3 commented 2 years ago

I would try to reproduce these issues on GNOME (which is my usual choice of desktop environment), but it's not working very well on the Intel Arc A380 right now and the instability prevents Minecraft from starting.

At the very least, KDE Plasma 5.26 seems to allow X11 applications to handle scaling themselves rather than making the compositor do it. For Minecraft that works out, since the game scales to whatever resolution it's given... only problem is that the window size starts at 100% scaling and needs to be made larger, and that it's slower than a native Wayland application.

gianni-rosato commented 2 years ago

KDE’s downscaling is not a problem on most apps, considering the performance cost is negligible. However, with Minecraft being a game, it definitely costs frames. Is patching GLFW worth it? Or, can the platform hint I described be provided & fix everything? Thank you for your replies as well!

theofficialgman commented 1 year ago

copying from Sodium dev chat as this is the proper place for this:

in response to this:

It doesn't seem to fix fractional scaling for me. For example, on KDE Plasma with a 3840x2160 display using 150% scaling, the game uses a resolution of 5120x2880 in full screen (two times the size of the virtual coordinate space of 2560x1440), which is nearly 80% more physical pixels the game needs to render before the compositor decides to scale it back down.

ok did some testing and research on that. glfw doesn't support the individual compositors wayland fractional scaling hacks.

integer scaling works properly on wayland (2X, 3X, etc) and the resolution matches the monitor resolution. since compositors implemented their own hacks for "fractional" scaling on wayland (using the next up integer scaling option and then downsampling) this is exactly what happens on glfw wayland as well. eg: 1.5X wayland scale actually renders at a higher resolution (this is the case for now everywhere on wayland till recently merged wp-fractional-scale-v1 gets implemented in compositors) and then downsamples to 1.5X

Wayland: selected scaling -> rendered resolution (wraps back around to native at integer resolutions) 2 -> 3840x2160 1.75 -> 4388x2468 1.5 -> 5120x2880 1.25 -> 6144x3456 1 -> 3840x2160

these are the results from minecraft, you can see that it follows a variant of the "draw at 2X then scale it down" approach for non-integer scales: monitor_resolution*2/scale eg: 3840*2/1.5=5120 IMHO, this is better than xwayland with glfw which looks like this:

XWayland: selected scaling -> rendered resolution (continues to get lower resolution past 2X) 2 -> 1920x1080 1.75 -> 2192x1234 1.5 -> 2560x1440 1.25 -> 3072x1728 1 -> 3840x2160

GLFW will NOT support wayland fractional scaling automatically when compositors update. it will need its own code changed (like this PR: https://github.com/glfw/glfw/pull/2215). This means that no matter what, fractional scaling simply will not work the same as fractional scaling on X11 on GLFW in the GLFW binary from lwjgl 3.3.1, which is built from GLFW commit https://github.com/glfw/glfw/commit/97da62a027794d9ff0f4512268cb9a73a8fb5073

theofficialgman commented 1 year ago

copyed from sodium dev chat regarding the platform hint:

If I change those errors to warning in source and built glfw without X11 support, then minecraft "just works" (since you don't have to specify the hint if X11 support isn't there).

no custom glfw would be necessary if sodium implemented the wayland hint (wayland support is part of default binary from lwjgl 3.3.0+) and changed these two to non-fatal errors glfwPlatformSetWindowIcon

glfwPlatformFocusWindow

idk if you could easily patch it out, you could just disable that functionality from minecraft if wayland is detected

I am assuming setwindowicon and focuswindow are being explicitly called somewhere

the window icon missing isn't a big deal (used to it being missing on other versions of minecraft anyway) and forcing window focusing simply isn't allowed on wayland and probably never will be

gianni-rosato commented 1 year ago

Any update on this ?

theofficialgman commented 1 year ago

@gianni-rosato refer to my messages above where I already fully anwered the the question and gave you links to issues/PRs to track.

KDE 5.27 will be the first release to ship wp-fractional-scale-v1 support since it was merged into KWin. WLRoots merged support 4 days ago, no clue when a release will hit with support. Mutter (GNOME compositor) does NOT have support merged, it is still in the works so a release with it is still a long way off from hitting distros.

the GLFW PR for wp-fractional-scale-v1 has stalled as well.

when KDE 5.27 starts shipping in distros (Ubuntu 23.04, Fedora 38 in April) I will probably test the in progress GLFW PR and see if it is "good enough" for minecraft specifically.

theofficialgman commented 1 year ago

I am back to report that I upgraded to 23.04 and installed kde proposed 5.27

unfortunatly the glfw PR is a no go. it results in lower than native resolution. in addition, it also breaks the mouse in minecraft

theofficialgman commented 1 year ago

Problem: When launching the game with fractional scaling enabled at 1.5x on my display, the game runs at lower resolution. I am on the Framework Laptop & my display is 2256x1504 but the game will run at 1503x1002. This is because Minecraft runs on XWayland, & X11 doesn't support fractional scaling.

however, on KDE 5.26+ at least, you can eneable the new legacy X11 applications scaling setting which lets xwayland applications like the default glfw in minecraft render at your native monitor resolution even with wayland fractional scaling

image

so that is what I have been using. works great and there are no changes to minecraft or its libraries necessary.

Enderteck commented 10 months ago

Any updates on Wayland support ?

Why if you don't need fractional scaling ?

rhjdvsgsgks commented 10 months ago

Any updates on Wayland support ?

Why if you don't need fractional scaling ?

glfw already support run minecraft under native wayland. but it hasnt tagged yet, so you need to build from source see also: https://github.com/CaffeineMC/sodium-fabric/issues/1624#issuecomment-1890439064

jellysquid3 commented 10 months ago

The situation hasn't changed much over the past few years with Wayland's fractional scaling support. At least there is now a protocol to tell clients what fractional scale to use, but very few applications currently support it, and GUI toolkits (GTK, Qt) either can't use it, or have severe issues when forced to use it. Even getting Firefox to render without downsampling is impossible, and that's basically the "gold standard" as far as Wayland applications go.

The important part though, is that GLFW itself doesn't support fractional scaling, and we don't know if/when this will change, especially when other toolkits are lagging behind. And it really doesn't make sense for Sodium to push Wayland by default, when fractional scaling is becoming increasingly common. The performance degradation is just too severe (often halving frame rates, or more) and users are more likely to care about this in an optimization mod than the other minor issues using Xwayland has.

If you really want to use Wayland natively-- and keep in mind there are good reasons to do that if you aren't affected by fractional scaling problems-- then you can use other mods to do it.

theofficialgman commented 10 months ago

The situation hasn't changed much over the past few years with Wayland's fractional scaling support. At least there is now a protocol to tell clients what fractional scale to use, but pretty much no application supports it, and GUI toolkits (GTK, Qt) either can't use it, or have severe issues when forced to use it. Even getting Firefox to render without downsampling is impossible, and that's basically the "gold standard" as far as Wayland applications go.

@jellysquid3 Wayland Fractional Scaling in QT6 has been functional and implemented for over a year now https://pointieststick.com/2022/12/16/this-week-in-kde-wayland-fractional-scaling-oh-and-we-also-fixed-multi-screen/ It is also available in SDL (https://github.com/libsdl-org/SDL/pull/5906).

Obviously it requires the window manager to support the protocol as well and KWin supported it on day 1 and GNOME shortly after as well. When plasma 6 releases on Feb 28th the entire KDE software suite will move to QT6 and automatically gain support. Some applications are already using QT6 as a backend and have support already.

Even getting Firefox to render without downsampling is impossible, and that's basically the "gold standard" as far as Wayland applications go.

Not sure why you are so out of the loop. Firefox has had wayland fractional scaling support since august https://www.phoronix.com/news/Firefox-Fractional-Scale-v1 . It is still disabled by default but works great when enabling it.

jellysquid3 commented 10 months ago

Wayland Fractional Scaling in QT6 has been functional and implemented for over a year now...

And very few applications are using QT6. The vast majority are still using Qt5/GTK4. It will take a number of years before we see applications adopt Qt6. Yes, the situation will improve now that compositors support it, but with the exception of a few applications (Mpv, for example), nothing really supports fractional scaling w/ hardware acceleration.

Not sure why you are so out of the loop.

With all due respect, you have clearly not tried using the functionality. Firefox is catastrophically broken (any pop-up window does not render correctly, completely breaking context/extension menus, etc) on all compositors. This is actually a regression compared to the prior functionality (setting the buffer scale in user preferences manually), since at least then menus would sorta render correctly. Even if these regressions didn't exist, it still doesn't render at a fractional scale correctly, and looks blurry compared to the last Firefox ESR w/ the old preference.

theofficialgman commented 10 months ago

And very few applications are using QT6. The vast majority are still using Qt5/GTK4. It will take a number of years before we see applications adopt Qt6. Yes, the situation will improve now that compositors support it, but with the exception of a few applications (Mpv, for example), nothing really supports fractional scaling w/ hardware acceleration.

Well in 1-2 months we will have the 200+ KDE software suite applications running QT6. That is nothing to sneeze at and for a regular user that might be every application that they use (outside of a web browser). QT6 has been out for a bit over 3 years now and developers have been transitioning since then. For sure some applications will take more time than others but, at least for me, all my applications that previously used QT5 have already transitioned to QT6.

I don't use VLC (for many reasons but I know it is popular) and it has a QT6 version nearing merge https://code.videolan.org/videolan/vlc/-/merge_requests/4783

So, to me, it looks like the only real applications missing are small applications that never get updated anyway.

With all due respect, you have clearly not tried using the functionality. Firefox is catastrophically broken (any pop-up window does not render correctly, completely breaking context/extension menus, etc) on all compositors. This is actually a regression compared to the prior functionality (setting the buffer scale in user preferences manually), since at least then menus would sorta render correctly.

I actually have used it and had not noticed that issue until you pointed it out.

Regardless though, none of this affects sodium. All that hinges on the stalled GLFW PR https://github.com/glfw/glfw/pull/2215 . That PR still needs to merge, a new release of LWJGL cut with glfw that includes it, and mojang adopts the new LWJGL version.

jellysquid3 commented 10 months ago

I'm not sure why you are arguing with me. My point is very clear: Today, these problems are still not solved. I'm not saying the problem will never be solved, but in the time that has elapsed from this issue being opened, the situation has not changed any in regards to Sodium feasibly being able to push Wayland by default. And since other mods have since appeared to do this, it doesn't make sense for us to focus on it ourselves anymore -- hence the issue was closed.