User:AbhinavPraveen/Optimizing Wine and Proton on Gentoo

Article description::This guide lists some optimizations to Wine and Proton and how to apply them on Gentoo.

Esync
If your user is called foo. Then simply append the following to /etc/security/limits.conf:

Esync will then be enabled by default in Proton and, if an Esync capable Wine is selected, Esync can be toggled in Lutris. You may also be able to enable it by setting WINEESYNC=1 as an environment variable. Depending on the implementation, you may also see "esync: up and running." in the logs when enabled and used.

Fsync/Futex2
Fsync is an optimization that requires an experimental kernel patch to work. One should first read /etc/portage/patches. After this, one can easily acquire a good selection of patches by cloning Frogging-Family/linux-tkg and finding the patch closest to their kernel version. If for example, you are running kernel 5.10.27, you should navigate to linux-tkg/linux-tkg-patches/5.10 and move your selected patches to /etc/portage/patches/sys-kernel/gentoo-sources-5.10.27:5.10.27. The patches listed below are used by the author.

Then, making sure that the kernel is eselected, enable CONFIG_FUTEX2 using your chosen menuconfig tool under /usr/src/linux and build the kernel. See Kernel/Configuration for more information. After booting into the new kernel, one can check dmesg if the option is enabled as follows:

Following this, Proton will enable Fsync/Futex2 by default, the option can be toggled in Lutris when using a compatible Wine version and can be enabled by setting the environment variable: WINEFSYNC=1. Depending on the implementation, you may also see "futex2: up and running." in the logs when enabled and used.

Wine
The portage in-tree Wine is not compatible with Esync or Fsync. One can acquire a compatible Wine as follows. First go to https://github.com/lutris/wine/releases and pick a version and copy the link to its source files e.g https://github.com/lutris/wine/archive/refs/tags/lutris-6.21-5.tar.gz. The latest version is often fine. Then create a local overlay as described in Custom ebuild repository named, for example, localrepo. Copy the portage in-tree wine-vanilla ebuilds to the overlay and replace the source files with the Lutris source. Note that this well typically not be a wine-vanilla build however, if we were to copy to the wine-staging ebuild, portage would attempt to apply the staging patches a second time on top of our Lutris source which (typically) already has these applied. While this may not be the ideal way to do this, it is quick and easy.

Find the existing in-tree wine ebuild that is closest to the Lutris wine version you have chosen. If they have the same major version, in this case it would be 6.21, skip the following step. If not, create it from a similar ebuild. If, for example, our chosen Lutris major version (6.21) does not have an ebuild but a nearby version (6.22) does:

Then open the selected ebuild in a text editor. Then fine the following line: SRC_URI="https://dl.winehq.org/wine/source/${MAJOR_V}.${MINOR_V}/${MY_P}.tar.xz" and replace it with the URL for the Lutris/Wine source e.g SRC_URI="https://github.com/lutris/wine/archive/refs/tags/lutris-6.21-5.tar.gz" Then in the ebuild's src_unpack, after "default" is called, add "mv "${WORKDIR}"/wine-lutris-6.21-5 "${WORKDIR}"/wine-6.21" replacing 6.21-5 with your chosen Lutris Wine verion and 6.21 with with the major version (i.e excluding -5 from 6.21-5). Then comparing the original ebuild and the new one, you should see something resembling: {{Cmd --- /var/db/repos/gentoo/app-emulation/wine-vanilla/wine-vanilla-6.21.ebuild	2021-11-06 22:09:39.000000000 +0000 +++ /var/db/repos/localrepo/app-emulation/wine-vanilla/wine-vanilla-6.21.ebuild	2021-11-27 19:15:09.689676215 +0000 @@ -19,7 +19,7 @@ 	#KEYWORDS="" else MAJOR_V=$(ver_cut 1) -	SRC_URI="https://dl.winehq.org/wine/source/${MAJOR_V}.x/${MY_P}.tar.xz" +	SRC_URI="https://github.com/lutris/wine/archive/refs/tags/lutris-6.21-5.tar.gz" KEYWORDS="-* ~amd64 ~x86" fi S="${WORKDIR}/${MY_P}" @@ -304,6 +304,7 @@ 	fi
 * diff -u /var/db/repos/{gentoo,localrepo}/app-emulation/wine-vanilla/wine-vanilla-6.21.ebuild|output=

default +	mv "${WORKDIR}"/wine-lutris-6.21-5 "${WORKDIR}"/wine-6.21

plocale_find_changes "${S}/po" "" ".po" } }}

Then use repoman to create the Manifest and build the package as usual.

Finally, select the wine version with eselect wine if desired. You should then see:

You can then select this version in Lutris.

Realtime Scheduling
By running the game as a 'realtime' proces, you can tell the scheduler to, up to a specified fraction of cpu-time (95% by default), always run tasks from the game before any other task. Note that this a bit of a hack and will not help in all circumstances. For example, if the game takes up so much CPU time that the GPU drivers cannot run, then you will not get any frames. By default, only root can set realtime process. We will use setcap (from sys-libs/libcap) on a copy of /usr/bin/chrt to allow us to do this. Again, assuming that your username is foo:

Note that anyone that can misuse /home/foo/.bin/chrt can cause denial of service. Then you can use "/home/me/.bin/chrt --rr 5" as a command prefix in Lutris or "/home/me/.bin/chrt --rr 5 %command%" as a launch option in steam. The author also recommends setting "kernel.sched_rt_runtime_us=990000" in /etc/sysctl.conf allowing the game to use 99% of CPU time and setting skew_tick=1 in the kernel commandline. A similar approach can be used to set niceness instead.