FEX 2208 Tagged!
Some really exciting changes this month. Thunk stabilization out of the gate is a huge boon to tinkerers and a bunch of other things spread throughout!
The amount of work to reach this point can’t be understated. @neobrain has been putting forth a bunch of infrastructure work over the past few months which hasn’t been super visible to the end user. This month it culminated towards fixing a bunch of stability problems with thunks.
One of the biggest problems ends up being when a pointer is passed between the guest and host through thunks. X11’s XFree function is used for both x86 specific pointers and AArch64 pointers. This ends up being a problem since FEX-Emu uses jemalloc for its allocator while a guest application is highly likely to use glibc’s allocator. Passing the opposite one to either will crash either. We now distinquish between a “Guest” pointer and a “Host” pointer in our thunk of XFree, which significantly improves stability of X11 thunks.
We also now have our libGL thunk implicitly load libX11. Due to how FEX’s thunks work, we don’t pull in all of the library dependencies of a “real” library like libGL. Long term FEX-Emu will likely want to link to the same libraries that the real x86-64 library would have linked to. For now, libGL now relies on libX11 directly. This fixes an issue where libGL thunks wouldn’t work at all for any game launched from Steam.
Then the big pull request that does an absolute wackload of infrastructure work to make things work, Implement signature-based thunking of function pointers. This pull request is a bit complex to explain but it allows function pointers to be marshalled across the thunk architecture boundary safely. Allowing both x86-64 and AArch64 to call in to the other for code for whatever reason is necessary. I would recommend reading the pull request itself because the information is quite dense there.
Then some very minor changes the fixes some edge case behaviour.
- Make glXGetProcAddr of unknown address non-fatal
- Make glXGetProcAddr querying itself work
- Add some missing glX and GL functions that were missing.
- Nearly everything supported now, just some minor things missing
The take away for this effort is that OpenGL thunking is now significantly more stable. We don’t have a lot of games tested yet, but follow along at our wiki for documenting which games support thunks under FEX-Emu.
When OpenGL or Vulkan thunks are enabled, games are dramatically sped up. It is the recommended way to play a game but we need more testing coverage to ensure it is stable enough to use.
This is also why now if you’re running Ubuntu Jammy, we now provide the thunks pre-built in our official PPA for your enjoyment! Give it a try!
Fix edge-case instruction faulting behaviour
x86 has six instructions that explicitly fault in different ways. We weren’t handling RIP setting correctly on some of these.
This was uncovered by running Elden Ring inside of FEX. With this bug fixed FEX-Emu can now run the game if Denuvo is disabled by renaming the executables. Sadly it doesn’t seem like Snapdragon can run this game yet.
AVX initial implementation details
@Lioncache has been working away at making this feature a reality. Newer games coming out are starting to require AVX to run and FEX needs to support this. This is a necessary feature since we need to claim compatibility for any CPU feature that games use. So far the list of games we found is few that require the feature but it is going to become more common. The latest generation of game consoles will drive this feature over the next decade of releases.
This sets up the initial groundwork inside of FEX-Emu to support the feature, with instruction implementations coming in the next months.
Don’t expect this to run on any of your ARM devices any time soon though. We are going to require SVE with 256-bit register width to expose it. All current hardware either doesn’t support SVE at all, or only supports a 128-bit register width. Look forward to future hardware that ships with this feature.
FEXConfig quality of life improvements
This is cleaning up some of the rough edges inside of FEXConfig, making it easier to modify your config. Significantly less keypresses to open a config! Perfect!
Fix SOMA again
Due to how FEX changed some of its threading logic, we broke SOMA abusing the SETXID signal. This is now resolved and the game runs under FEX-Emu again.
Fix Static Register Allocation in signal handlers
Applications relying on signals would very likely have crashed for a while due to this regression. With this resolve these games are stable again.
FEXRootFSFetcher automation options
FEXRootFSFetcher now has command line options for automatically choosing distro image and setting it up in config. This is useful for containers embedding FEX and wanting a fresh rootfs instead of shipping it. It also does a runtime check for any image tooling programs before executing, fixing a spurious error message.
Fix hang in Proton from close_range syscall
Proton would sometimes hang due to a close_range syscall trying to close all file descriptors. Make FEX a bit smarter about closing FDs with this syscall which fixed the bug.
FEXBash change PS1 description
When running FEXBash it can be confusing for new users how it is behaving. Now we show the current operating path, user, and FEXBash as a prefix. Hopefully this can be less confusing to new users that FEXBash isn’t a VM, or docker style chroot.
Support Linux 5.19 passthrough
Not much changed from FEX’s perspective here. Some minor DRM changes that naturally work themselves out.
Only initialize perf map file if profiling is enabled
Sorry about filling up your /tmp folder with empty files. This has been resolved.
Add pidfd_open syscall wrapper for compiling on older Linux distributions
Thanks to @wannacu for this fix. Our testing of older Linux distributions is quite spotty since FEX-Emu only officially supports back to glibc 2.31 distros. This adds a wrapper utility for this syscall so older versions of Linux can compile FEX. Your mileage may vary since FEX-Emu doesn’t officially support it although.
Developer specific improvements
Static pie will never work due to glibc limitations around dlopen that FEX needs for thunks. Remove the option entirely to ensure no one tries to use it.
FMT updated to 9.0.0
Newest release is best release
Bitness of syscall handler improvements
We were setting up both 32-bit and 64-bit syscall handlers upon initialization. Now we only initialize one or the other. Saves a bit of memory and startup time shaves some microseconds off.
Vulkan-Headers included in External
It’s no longer required as a install dependency on the host. We need to handle all Vulkan signatures, not just what is available on the host. Makes compiling Vulkan thunks slightly less painful.
- Cortex-X1C supported in CPUID
- Support a globally installed Config file
- Support installing many json files from FEX Data folder
- Disable UnitTestGenerator since it is unused
- Assume optimizing LogManager assertion functions
- Support executable names being picked up for wineserver.
- Useful to see if a Windows game is doing something that our telemetry picks up
- Removing last usage of raw IR arguments in emulation backends
- x86_64: Migrate args over to named IR arguments
- json_ir_generator: Remove Args() functions from IR structs
- These make it a lot easier to see what arguments are being used and why