FSR 4.1.0 with Vanilla Wine on RDNA3: Yes, it actually works

So I believe I have gotten FSR4 on RDNA3 working with vanilla Wine and thought to share how it all works. I figured I would post my findings to help other non-proton folk use FSR4 on RDNA3 cards without all the mystery behind magical environment variables and scripts that only work with Proton.

1. FSR4 support for RDNA4 cards was introduced to vkd3d-proton 3.0 on Nov 17th, 2025. But… RDNA3 could use it too, if you knew what to do.

FSR4 support

We added support for AGS WMMA intrinsics through VK_KHR_cooperative_matrix and VK_KHR_shader_float8, which is enough to support FSR4. Note that these shaders are tightly coded for AMD GPUs with some implementation defined behavior (particularly around matrix layouts), and they will not necessarily work on other GPU vendors.

There is also a quite hacky emulation path of this which relies on int8 and float16 cooperative matrix support, which can run on older GPUs at significant performance cost (and some cost to theoretical correctness).

Note that the default “official” build of vkd3d-proton only exposes this feature when the native
VK_KHR_shader_float8 is properly supported, i.e. RDNA4+ only. The emulation path is available when building from source with the appropriate build flags. The decision to not include this emulation path by default is over my pay grade. The aim is to be able to ship FSR4 in a more proper way in Proton.

2. As stated in the release notes, vkd3d-proton requires a specific build option (-Denable_extended_emulation) for RDNA3 cards to even attempt to use FSR4 and is not enabled by default.

The easy route is to just download the proton-cachyos package and extract the dxgi.dll, d3d12.dll and d3d12core.dll 64bit files. Or, of course, build vkd3d-proton with the required options and download the latest dxgi.dll from DXVK.

#ifdef VKD3D_ENABLE_EXTENDED_EMULATION
        else
        {
            /* Don't expose this by default in official builds.
             * The decision is above my paygrade.
             * Pre-RDNA4 build requires extra env-var hacks on top to make it work. */
            /* In the fallback, we use u8 as an intermediate format. */
            if (fmt->AType == VK_COMPONENT_TYPE_UINT8_KHR)
                supports_8bit_a = true;
@@ -2756,6 +2761,7 @@ static bool vkd3d_supports_minimum_coopmat_caps(struct d3d12_device *device)
            if (fmt->CType == VK_COMPONENT_TYPE_UINT8_KHR)
                supports_8bit_c = true;
        }
#endif

3. As stated in the code comment, even if we build vkd3d-proton with the emulation option enabled, we will still need an environment variable to be set before FSR4 will work with RDNA3.

As far as I can tell, we only need to set this envvar:

DXIL_SPIRV_CONFIG=wmma_rdna3_workaround

4. Next we need the FSR4 DLLs, which the CachyOS Proton build has a script for, but you can just download them directly from AMD:

version: 4.0.0_67A4D2BC10ad000
https://download.amd.com/dir/bin/amdxcffx64.dll/67A4D2BC10ad000/amdxcffx64.dll

version: 4.0.1_67D435F7d97000
https://download.amd.com/dir/bin/amdxcffx64.dll/67D435F7d97000/amdxcffx64.dll

version: 4.0.2_68840348eb8000
https://download.amd.com/dir/bin/amdxcffx64.dll/68840348eb8000/amdxcffx64.dll

NOTE: See my later post about getting FSR 4.0.3 working.

5. But wait, there’s more! TM

According to the OptiScaler folks, we also need amdxc64.dll:

cdozdil

Hi,

Current flow for Fsr4Update is like this:

  1. amd_fidelityfx_dx12.dll loads amdxc64.dll
  2. Using AmdExtD3DCreateInterface from amdxc64.dll query IAmdExtFfxApi
  3. OptiScaler intercepts this call and returns a custom implementation of IAmdExtFfxApi
  4. amd_fidelityfx_dx12.dll calls UpdateFfxApiProvider method of OptiScaler’s custom IAmdExtFfxApi
  5. OptiScaler loads amdxcffx64.dll and returns result of amdxcffx64.dll’s UpdateFfxApiProvider method

For testing FSR4 on Linux at least you should put amdxc64.dll and amdxcffx64.dll into game folder so OptiScaler can load and use them.

Turns out Proton makes their own shim for amdxc64.dll, so we probably don’t want the official AMD file from the Windows driver:

$ grep -rni amdxc64 *
libs/vkd3d/device.c:579:     * leading to bad performance in some cases. Currently only affects Proton-GE which ships amdxc64.dll shim by default. */
libs/vkd3d/device.c:3494:     * like FSR and AntiLag check if amdxc64.dll is loaded, then attempt
libs/vkd3d/device.c:3506:        device->vendor_hacks.amdxc64 = LoadLibraryA("amdxc64.dll");
libs/vkd3d/device.c:3507:        if (device->vendor_hacks.amdxc64)
libs/vkd3d/device.c:3508:            INFO("Loaded amdxc64.dll successfully.\n");
libs/vkd3d/device.c:3516:    if (device->vendor_hacks.amdxc64)
libs/vkd3d/device.c:3517:        FreeLibrary(device->vendor_hacks.amdxc64);
libs/vkd3d/vkd3d_private.h:5495:        HMODULE amdxc64;
static void d3d12_device_init_vendor_hacks(struct d3d12_device *device)
{
    /* We don't do anything with this library directly, but various AMD provided dlls
     * like FSR and AntiLag check if amdxc64.dll is loaded, then attempt
     * calling into it. On Proton, this DLL is purely a shim intended to forward calls
     * to where they belong.
     * This DLL is provided through external means (at least for now),
     * but the logical thing to do is to load the DLL when the d3d12 device is created,
     * since this is literally the name of the d3d12 driver on Windows.
     * Don't bother with 32-bit since 32-bit d3d12 is not really a thing. */
    (void)device;

6. …and in the darkness, bind them!

Basically:

  1. Extract amdxc64.dll, dxgi.dll, d3d12.dll, d3d12core.dll from proton-cachyos.
  2. Download amdxcffx64.dll from AMD directly.
  3. Place the Proton amdxc64.dll shim and amdxcffx64.dll in ~/.wine/drive_c/windows/system32
  4. Symlink or copy dxgi.dll, d3d12.dll, d3d12core.dll next to the game binary (the .exe file for the game, NOT a launcher .exe). E.g, “TQ2-Win64-Shipping.exe”. But make sure you backup any existing DLLs in the game directory by appending _original or make a new directory named original_files and place the old files there.
  5. Open a terminal and run winecfg. Set DLL overrides for dxgi, d3d12, d3d12core and set “Windows Version” to “Windows 11”.
  6. Finally, we need the all important envvar: DXIL_SPIRV_CONFIG=wmma_rdna3_workaround. This is probably best done with a .desktop file or a simple shell script with something like:
#!/bin/bash
#Titan Quest II with FSR4 "upgrade" on RDNA3
#set vkd3d-proton envvar for RDNA3
export DXIL_SPIRV_CONFIG=wmma_rdna3_workaround
#you can also manually add Wine DLL overrides as an environment variable
export WINEDLLOVERRIDES="dxgi,d3d12,d3d12core=n,b"
#stop wine from spamming the console log
export WINEDEBUG=-all
#run the game
cd /path/to/game/binary
wine "TQ2-Win64-Shipping.exe"

And now you can game with FSR4 without needing multilib and cursed 32bit package cruft. If you actually want/need 32bit packages, then just use cachyos-proton. Its simpler, but I like doing things the hard way, lol. And I guess now you know what is actually going on behind the scenes: no longer can you claim ignorance as to what FSR4_UPGRADE=1 does (just downloads amdxcffx64.dll and places it in the system32 directory).

Also, this will only work for games that use FSR3.1. Otherwise, you will need Optiscaler to use FSR4. I prefer figuring out what is going on and why, so if I can manually get the game to “JUST DO IT!”, then I prefer that (even if it is a slog figuring out what the hell is going on). But OptiScaler is nice too and an amazing project that works on both Windows and Linux.

If everything is working, the vkd3d-proton log should show something like:

info:  Game: TQ2-Win64-Shipping.exe
info:  Found device: AMD Radeon RX 7600 XT (radv 26.0.99)
info:vkd3d-proton:d3d12_device_init_vendor_hacks: Loaded amdxc64.dll successfully.
info:vkd3d-proton:vkd3d_compute_shader_interface_key: Using DXIL_SPIRV_CONFIG = wmma_rdna3_workaround

FSR4 takes waaaaay more GPU resources than FSR3.x, but does look better. Below is FSR set to “Ultra Performance” with all game settings set to “Epic” so we can see how the upscaling artifacts look more easily. And without frame gen since the fake frames throw off screenshots. For some reason AMD Anti-Lag 2 isn’t working (haven’t had time to figure out what is going on yet).

FSR4 “upgrade”



FSR3.x (whatever ships with TQ2)

To disable the “FSR4 upgrade” simply rename the amdxc64.dll shim to amdxc64.dll_ and restart the game.

FSR4 has less weird “random noise” than FSR3 on the main screen, especially on the boat and (dear god) the leaves fluttering around. Not sure if the screenshots do it actual justice here.

In the end, I can see why AMD is not going to release FSR4 for RDNA3, while it does look better, it performs worse than XeSS for roughly the same visual quality in most cases.



how to propose build install ?

need a package, with wine, to make script or else according to a version.

for dl download, we need to have a choice to select

Basically, to change FSR4 versions, you simply replace the amdxcffx64.dll in the Wine system32 directory with the version you want. That said, you can actually place both the amdxc64.dll shim and amdxcffx64.dll file in the same directory as the game binary along with dxgi.dll, d3d12dll and d3d12core.dll. And only that game will get the “upgrade” treatment. Placing the FSR4 files in system32 makes the “upgrade” global for any game with FSR3.1–when using vkd3d-proton DLLs taken from the proton-cachyos package (or when built from git with the aforementioned build option).

As far as package versioning goes: if you are on Arch, you already have The Latest TM. So no need to overthink this. If you are on an LTS distro like Ubuntu… well, they can figure out what version of Mesa and Wine are needed to get this working. The base Arch wine and mesa-git packages, or at least CachyOS packages, will work out of the box. Literally copy 5 files and set 1 environment variable for vanilla Wine to work with FSR4. Of course, you can use symlinks for these files with a script that links to a specific FSR4 version. Its not hard to script something to simplify managing this for each game.

If vkd3d-proton cannot find amdxc64.dll, the “upgrade” won’t work. That was the second missing puzzle piece that Proton ships with but Wine does not. The first was vkd3d-proton being built with the emulation option enabled.

I think I may have also gotten FSR 4.0.3 working… Not entirely sure though.

The amd_fidelityfx_upscaler_dx12.dll from AMD’s FSR SDK v2.1.0, or “Redstone” release, combines FSR 2.3.4, 3.1.5 and 4.0.3 into one file. Simply replacing an older amd_fidelityfx_upscaler_dx12.dll with this newer version will still only use FSR 3.1.5 when the game enables FSR. Further more, the Proton FSR4 upgrade trick won’t actually use the 4.0.3 code in this file because it loads 4.0.2 (or older) from amdxcffx64.dll. On Windows, there is a registry key that can turn on 4.0.3 for “supported” cards with the “Redstone” amd_fidelityfx_upscaler_dx12.dll when updating an older version for a game. However, simply renaming this newer amd_fidelityfx_upscaler_dx12.dll to amdxcffx64.dll and placing it in the system32 directory worked! FSR4 is loaded through the Proton hack. And since this newer DLL only contains (as far as I am aware) FSR 4.0.3, then that is what’s being used!

Boom! We got FSR 4.0.3 on Linux. I’ll upload some comparison images after playing around with this some more.

Also, and I think this is old news to most, you can use this “Redstone” release to update games using the older amd_fidelityfx_dx12.dll by renaming amd_fidelityfx_loader_dx12.dll to amd_fidelityfx_dx12.dll and then copying it and amd_fidelityfx_upscaler_dx12.dll and amd_fidelityfx_framegeneration_dx12.dll to the game directory where the original amd_fidelityfx_dx12.dll was located (backing up the original first). I tested this with Hell Is Us and got higher FPS at the same settings!

Here are the game settings:

Yes. I accidentally set Effects to Low instead of Epic…


FSR 4.0.3 (Proton hack + “Redstone”)

Rename the “Redstone” amd_fidelityfx_upscaler_dx12.dll to amdxcffx64.dll and place in system32 along with the amdxc64.dll. Alternatively, (for local scope and deduplication) place both of these files next to the game binary and simply make a relative symbolic link of the Redstone upscaler file in the game directory: ln -s amd_fidelityfx_upscaler_dx12.dll amdxcffx64.dll:

Frame rate drops crazy hard on my RX 7600 but visual quality looks great for such low resolution. Many issues with flickering (on the boat), ghosting (fluttering leaves) and random noise (in the ocean waves) are essentially eliminated. Shadows are weirdly blocky compared to FSR3.x though. Not everything is better, but the annoying aspects of FSR3 are gone, and the minor regression with shadow quality is not a big loss. On the character creation screen, FSR3.x had this annoying flickering with the texture of the shirt. FSR4 looked excellent and without any flickering. Most differences cannot be captured by still images, since the frame-to-frame variations are the biggest give-away when using FSR3 or even XeSS.




FSR 3.1.5? (updated original game files to “Redstone”)

No real improvement over the original game files, as expected.




So I did some more testing, and it turns out one can globally update all games that use any recent version of FSR (2, 3 and 4) by simply adding the new “Redstone” DLLs and the Proton amdxc64.dll shim (for FSR 4.0.3 “upgrade” of FSR3.1 games) to the Wine system32 directory and move all the old FSR DLLs in the game directories to a fsr_original dir so each game will only load the FSR files from the system32 dir. This deduplicates files and allows one single place to manage FSR updates.

  1. Download the FidelityFX SDK 2.1.0 “Minimal package” to get the signed DLLs.

  2. Rename amd_fidelityfx_loader_dx12.dll to amd_fidelityfx_dx12.dll

This “loader” DLL allows older FSR games to use the newer split FSR DLLs (upscaler + framegen) from the Redstone release.

  1. Make a relative symbolic link to the Redstone amd_fidelityfx_upscaler_dx12.dll for the FSR 4.0.3 upgrade using ln -s amd_fidelityfx_upscaler_dx12.dll amdxcffx64.dll.

This allows the Proton amdxc64.dll shim to load FSR 4.0.3 on Linux, otherwise you only have access to 4.0.2 and below using the amdxcffx64.dll files from AMD’s website.

These then make up all the core DLLs required to use FSR 2.x, 3.x and 4.x on Linux with Wine or Proton and will provide FSR 2.3.4, 3.1.5 or 4.0.3 to all games that support them or can use the “FSR4 upgrade”.

I found a copy of the int8 FSR 4.0.2 DLL here.

Theoretically, this version should work on AMD RDNA2 as well as Nvidia and Intel GPUs. I’ve also tested that it does not require the DXIL_SPIRV_CONFIG=wmma_rdna3_workaround envvar (which is only needed for fp8 on fp16 emulation used by RDNA3 to run the official fp8 FSR4 algorithm).

Its a chonky little guy at 40.7 MB (38.8 MiB). That’s nearly twice of the size of the official Redstone 4.0.3 release.

I didn’t know what version of FSR4 this DLL was until I looked at it with ImHex:

Here is the official Redstone 4.0.3:

I’ve heard, that on Windows, the int8 FSR4 algorithm works better than the fp8 algorithm that AMD has shipped publicly. That made me curious enough to try it out and see if I can squeeze a little bit more performance from my wimpy RX 7600.

It turns out that, yes, it is slightly faster. I’m seeing roughly an 11 to 12 percent uplift in FPS with no discernible loss in visual quality over the fp8 algorithm. So, for RDNA3 and older GPUs, this is the better option if wanting to use FSR4. And the best part is, it requires less effort! No special build of vkd3d-proton and no envvars needed!

I’m still using TQ2 pre-release as my test bed. I’ve set everything to Low except Shadows → High (because they flicker otherwise) and Anti-Aliasing, Textures, View Distance → Epic (so it actually looks good). With those set, the game looks nice and is playable (if barely, 40FPS is my minimum for playability). Honestly, in someways the game looks better without DoF and Bloom.

NOTES: Tests were conducted under Niri, which is a very lightweight compositor with in-game vsync off and the frame-limiter set to 60 FPS. The int8 upscaler DLL was placed with the version appropriate 4.0.2 framegeneration and loader DLLs and used the latest github actions build for both dxvk and vkd3d-proton. The fp8 upscaler used the same dxvk dxgi.dll as the int8 test, but required using the vkd3d-proton DLLs extracted from proton-cachyos since I was too lazy to build it from source.


fp8 FSR4 (4.0.3)

Baseline, FSR “Performance (2.0x)”.

40.38 and 35.60 FPS


Baseline, FSR “Ultra Performance (3.0x)”.

46.23 and 40.77 FPS



int8 FSR4 (4.0.2) The little engine that could. TM

FSR “Performance (2.0x)”

45.66 and 39.64 FPS


FSR “Ultra Performance (3.0x)”

52.75 and 45.76 FPS


Looks like AMD just released FidelityFX SDK 2.1.1.

This revision is a minor patch release that fixes a number of documentation links and performs housekeeping on the repository to reduce confusion when linking.

But, it seems like a nothingburger of a release for gamers.

For game developers, it is likely a welcome improvement when working with AMD’s SDK.

And if you were wondering, I double checked the DLLs and… they are exactly the same.

$ sha256sum *.dll
61bebc329bf126f96e46e642e41e661e70fc01fc060f5ac523c67867c8e71fb0  amd_fidelityfx_denoiser_dx12.dll
3f5e674a59b400756e98ef31fd583a4eb08ad567ec8dee362886bc96e55ed347  amd_fidelityfx_framegeneration_dx12.dll
2f36843c3bb8c059621c10574e586a883ef337f2a549c67ecf3a82b3959ac238  amd_fidelityfx_loader_dx12.dll
f5ad8425de6bbac7a94569fe2771e2c766cf0a4e7d5a8e27ae8de129616b8a88  amd_fidelityfx_radiancecache_dx12.dll
3eab9a448db1ca09d5aba17d11df5b789649c11d60f1281f4be97bd007ac7d6d  amd_fidelityfx_upscaler_dx12.dll

A small PSA

In my previous post I forgot to caution, that since the int8 amd_fidelityfx_upscaler_dx12.dll is version 4.0.2, you would not want to mix it with the DLLs from the Redstone release (or this recent re-release of Redstone).

While we want better upscaling and FPS, we also want stability. And mixing random DLL versions is a no-no generally. And in particular, the “loader” DLLs are actually different. I am also uncertain of how decoupled the frame generation DLL is from the upscaler DLL. So, long story short: don’t mix and match.

To get a “full-stack” using the lonewolf int8 DLL from Reddit, you would want to:

  1. Download the FSR 4.0.2 int8 amd_fidelityfx_upscaler_dx12.dll here.

This int8 FSR4 version should work with Nvidia, Intel and AMD RDNA2+ GPUs.

  1. Download the FidelityFX SDK v2.0.0 “Minimal package”.

This is the FSR 4.0.2 release and these files should, in theory, play nice with the int8 upscaler DLL.

We only need to extract the signed amd_fidelityfx_loader_dx12.dll and amd_fidelityfx_framegeneration_dx12.dll files. We don’t need the fp8 amd_fidelityfx_upscaler_dx12.dll that is included with the SDK since we want to use the int8 file.

  1. Rename the amd_fidelityfx_loader_dx12.dll to amd_fidelityfx_dx12.dll.

This lets older games targeting amd_fidelityfx_dx12.dll use the newer split DLLs (upscaler + framegen).

  1. Create a relative symbolic link to amd_fidelityfx_upscaler_dx12.dll for the Proton shim to target for FSR4 upgrade:
ln -s amd_fidelityfx_upscaler_dx12.dll amdxcffx64.dll

This step is important. If you download amdxcffx64.dll from AMD (or let Proton do this for you), you will only get the fp8 algorithm when using “FSR4 upgrade”. We are tricking the Proton shim (amdxc64.dll) to load the int8 FSR4 4.0.2 code with this symbolic link, as this is what it targets when vkd3d-proton loads amdxc64.dll.

The official builds of VKD3D-Proton (d3d12.dll and d3d12core.dll) should work for “FSR4 upgrade” with RDNA3 since we don’t need to use the DXIL_SPIRV_CONFIG=wmma_rdna3_workaround envvar. The VKD3D-Proton DLLs from proton-cachyos were only needed to get the “FSR4 upgrade” to work with RDNA3 using the official fp8 algorithm. However, we do still require the amdxc64.dll shim from proton-cachyos, as VKD3D-Proton needs to load it for the “FSR4 upgrade” to work at all.

Hoo boy!

We gots an FSR4 4.1.0 leak yall!

The new amdxcffx64.dll can be found here.

Screenshot 2026-02-27 04-22-05

UPDATE:

It also looks like you can get the latest official 4.0.3 amdxcffx64.dll from the new Windows Driver.


Yet another PSA

And some more exciting news. I may be wrong on how the Proton amdxc64.dll shim works… Or at the very least, how it works with vanilla Wine. Turns out, the amdxcffx64.dll is never loaded! But that doesn’t mean we didn’t get FSR4 4.0.3 or the int8 FSR4 4.0.2 working! Those definitely worked. Just not the way it was supposed to (the FSR4 upgrade used the upscaler DLL directly to begin with). So not really a big deal, except I can’t actually test out this new FSR4 version since the shim isn’t loading the file it was supposed to load. My current shot-in-the-dark explanation, is that there must be a fall-back path that enabled the FSR4 upgrade using the upscaler DLL. (Which, ironically, is what I wanted anyways.) However, it should be loading the amdxcffx64.dll–which is a more modular way of updating the “FSR4 upgrade” code without having to replace the game’s upscaler and framegeneration DLLs. It’s a sneakier way of doing it and likely has lower chances of breaking a game.

TL;DR, the amdxc64ffx64.dll symbolic link to amd_fidelityfx_upscaler_dx12.dll did nothing! But the FSR4 upgrade still works and uses the FSR4 code contained in the upscaler DLL (as desired). This means you currently need to update the game’s upscaler DLL to use a newer FSR4 version for the “FSR4 upgrade”, rather than the amdxcffx64.dll.

You can see my horror in realizing I’m wrong slowly unfold here:

Did some looking and the Proton-GE-Custom source has amdxc64.dll patches that I need to sift through for why amdxcffx64.dll isn’t being loaded with normal Wine.

That said, I was correct in my understanding of how all this works:

PROTON_FSR4_UPGRADE

Automatically download amdxcffx64.dll and upgrade games with FSR 3.1 to use FSR 4. Version to download can be specified by supplying it as a value, like so PROTON_FSR4_UPGRADE="4.0.1", instead of 1. Downloads version 4.0.2 of the required DLL by default. This option also disables AMD Anti-Lag 2 currently due to various issues.

PROTON_FSR4_RDNA3_UPGRADE

Identical to PROTON_FSR4_UPGRADE but for RDNA3 GPUs. Enables some required compatibility options and downloads version 4.0.0 of the DLL by default.

This also explains why I couldn’t get AMD Anti-Lag 2 working with TQ2.

And from VKD3D-Proton, we see that it loads amdxc64.dll

static void d3d12_device_init_vendor_hacks(struct d3d12_device *device)
{
    /* We don't do anything with this library directly, but various AMD provided dlls
     * like FSR and AntiLag check if amdxc64.dll is loaded, then attempt
     * calling into it. On Proton, this DLL is purely a shim intended to forward calls
     * to where they belong.
     * This DLL is provided through external means (at least for now),
     * but the logical thing to do is to load the DLL when the d3d12 device is created,
     * since this is literally the name of the d3d12 driver on Windows.
     * Don't bother with 32-bit since 32-bit d3d12 is not really a thing. */
    (void)device;

#ifdef _WIN64
    if (device->device_info.properties2.properties.vendorID == 0x1002)
    {
        device->vendor_hacks.amdxc64 = LoadLibraryA("amdxc64.dll");
        if (device->vendor_hacks.amdxc64)
            INFO("Loaded amdxc64.dll successfully.\n");
    }
#endif
}

So, vkd3d-proton (d3d12.dll + d3d12core.dll) → amdxc64.dllamdxcffx64.dll was correct. And thus we need to dig deeper into amdxc64.dll.

And I’m back at it. Looking through the patches provided by proton-ge-custom we have:

$ grep -rnli amdxc * | sort
patches/wine-hotfixes/pending/0001-HACK-kernelbase-allow-overriding-dlls-for-DLSS-XeSS-.patch
patches/wine-hotfixes/wine-wayland/0305-amdxc-Port-to-SDK-headers.patch
patches/wine-hotfixes/wine-wayland/0306-amdxc-Add-stub-interface-for-IAmdExtD3DDevice8.patch
patches/wine-hotfixes/wine-wayland/0307-amdxc-Add-support-for-MLSR-WATERMARK-env.patch
patches/wine-hotfixes/wine-wayland/0308-amdxc-Properly-check-for-WMMA-support.patch
patches/wine-hotfixes/wine-wayland/0385-amdxc-atidxx-Remove-unused-header.patch
patches/wine-hotfixes/wine-wayland/0406-amdxc-Implement-FSR4-MLFG-override.patch
patches/wine-hotfixes/wine-wayland/0407-amdxc-Some-minor-code-cleanups.patch
patches/wine-hotfixes/wine-wayland/0412-amdxc-Introduce-user-control-for-MLFG-upgrades.patch
patches/wine-hotfixes/wine-wayland/0456-amdxc-Add-env-to-enable-MLFG-watermark.patch
README.md

In patch 0308 a debug channel is added for the amdxc64.dll

WINE_DEFAULT_DEBUG_CHANNEL(amdxc);

When running a throw-away proton-ge prefix, I have added this channel

export DXIL_SPIRV_CONFIG=wmma_rdna3_workaround
export WINEDEBUG=-all,+amdxc,+loaddll
export FSR4_WATERMARK=1
/path/to/GE-Proton10-32/files/bin/wine64 /path/to/"TQ2-Win64-Shipping.exe" \
2>&1 | tee /path/to/amdxc.log

Using the int8 FSR4 4.0.2 upscaler DLL we get:

$ grep -i amd amdxc.log
[...]
0024:trace:loaddll:build_module Loaded L"G:\\home\\user\\titan_quest_ii\\TQ2\\Binaries\\Win64\\amdxc64.dll" at 00006FFFFADD0000: builtin
35163.775:0020:0024:info:vkd3d-proton:d3d12_device_init_vendor_hacks: Loaded amdxc64.dll successfully.
0024:trace:amdxc:AmdExtD3DCreateInterface outer 000000001DC20080, iid {44085fbe-e839-40c5-bf38-0ebc5ab4d0a6}, obj 0000000011817690
LogAntiLag2: Error: AMD Anti-Lag 2 module failed to initialize for D3D12.
0024:trace:loaddll:build_module Loaded L"G:\\home\\user\\titan_quest_ii\\TQ2\\Binaries\\Win64\\amd_fidelityfx_upscaler_dx12.dll" at 00006FFFF86D0000: native
0024:trace:loaddll:build_module Loaded L"G:\\home\\user\\titan_quest_ii\\TQ2\\Binaries\\Win64\\amd_fidelityfx_framegeneration_dx12.dll" at 00006FFFF85B0000: native
LogXeSSCommonCoreModuleBase: Display: XeSS SDK version: 2.0.2, vendor: AMD, RHI: D3D12
LogXeSSCommonCoreModuleBase: Display: XeLL SDK version: 1.2.1, vendor: AMD, RHI: D3D12
LogXeSSCommonCoreModuleBase: Display: XeFG SDK version: 1.2.2, vendor: AMD, RHI: D3D12
01b0:trace:amdxc:AmdExtD3DCreateInterface outer 000000001DC20080, iid {b58d6601-7401-4234-8180-6febfc0e484c}, obj 00006FFFFAD86EF0
01b0:trace:amdxc:AmdExtD3DCreateInterface FSR 4 supported: 1
01b0:trace:amdxc:AMDFSR4FFX_UpdateFfxApiProvider 0000000007DCE3D0 0000000031989EF0 80
010c:trace:amdxc:AMDFSR4FFX_UpdateFfxApiProvider 0000000007DCE3D0 00000000077FF9C0 80
[...]

Curiously, no errors are logged about being unable to load amdxcffx64.dll or falling back to using the upscaler DLL either.

We get a slightly different log with framegeneration enabled:

[...]
0024:trace:loaddll:build_module Loaded L"G:\\home\\user\\titan_quest_ii\\TQ2\\Binaries\\Win64\\amdxc64.dll" at 00006FFFFADD0000: builtin
39136.230:0020:0024:info:vkd3d-proton:d3d12_device_init_vendor_hacks: Loaded amdxc64.dll successfully.
0024:trace:amdxc:AmdExtD3DCreateInterface outer 000000001DC20080, iid {44085fbe-e839-40c5-bf38-0ebc5ab4d0a6}, obj 000000001181F1F0
LogAntiLag2: Error: AMD Anti-Lag 2 module failed to initialize for D3D12.
0024:trace:loaddll:build_module Loaded L"G:\\home\\user\\titan_quest_ii\\TQ2\\Binaries\\Win64\\amd_fidelityfx_upscaler_dx12.dll" at 00006FFFF86D0000: native
0024:trace:loaddll:build_module Loaded L"G:\\home\\user\\titan_quest_ii\\TQ2\\Binaries\\Win64\\amd_fidelityfx_framegeneration_dx12.dll" at 00006FFFF85B0000: native
LogXeSSCommonCoreModuleBase: Display: XeSS SDK version: 2.0.2, vendor: AMD, RHI: D3D12
LogXeSSCommonCoreModuleBase: Display: XeLL SDK version: 1.2.1, vendor: AMD, RHI: D3D12
LogXeSSCommonCoreModuleBase: Display: XeFG SDK version: 1.2.2, vendor: AMD, RHI: D3D12
01b0:trace:amdxc:AmdExtD3DCreateInterface outer 000000001DC20080, iid {b58d6601-7401-4234-8180-6febfc0e484c}, obj 00006FFFFAD86EF0
01b0:trace:amdxc:AmdExtD3DCreateInterface FSR 4 supported: 1
01b0:trace:amdxc:AMDFSR4FFX_UpdateFfxApiProvider 0000000007DCE3D0 00000000319D9EF0 80
01b0:trace:amdxc:AmdExtD3DCreateInterface outer 000000001DC20080, iid {b58d6601-7401-4234-8180-6febfc0e484c}, obj 00006FFFF86B7320
01b0:trace:amdxc:AmdExtD3DCreateInterface FSR 4 supported: 1
01b0:trace:amdxc:AMDFSR4FFX_UpdateFfxApiProvider 0000000007DCE400 00000000319DE120 80
010c:trace:amdxc:AMDFSR4FFX_UpdateFfxApiProvider 0000000007DCE3D0 00000000077FF9C0 80
[...]

And, if you were curious, the Redstone fp8 shows:

And eureka!

All I needed to do was set FSR4_UPGRADE=1, lol!

[...]
0024:trace:loaddll:build_module Loaded L"G:\\home\\user\\titan_quest_ii\\TQ2\\Binaries\\Win64\\amdxc64.dll" at 00006FFFFADD0000: builtin
41368.397:0020:0024:info:vkd3d-proton:d3d12_device_init_vendor_hacks: Loaded amdxc64.dll successfully.
0024:trace:amdxc:AmdExtD3DCreateInterface outer 000000001E7C0080, iid {44085fbe-e839-40c5-bf38-0ebc5ab4d0a6}, obj 00000000123AD9B0
LogAntiLag2: Error: AMD Anti-Lag 2 module failed to initialize for D3D12.
0024:trace:loaddll:build_module Loaded L"G:\\home\\user\\titan_quest_ii\\TQ2\\Binaries\\Win64\\amd_fidelityfx_upscaler_dx12.dll" at 00006FFFF9840000: native
0024:trace:loaddll:build_module Loaded L"G:\\home\\user\\titan_quest_ii\\TQ2\\Binaries\\Win64\\amd_fidelityfx_framegeneration_dx12.dll" at 00006FFFF73B0000: native
LogXeSSCommonCoreModuleBase: Display: XeSS SDK version: 2.0.2, vendor: AMD, RHI: D3D12
LogXeSSCommonCoreModuleBase: Display: XeLL SDK version: 1.2.1, vendor: AMD, RHI: D3D12
LogXeSSCommonCoreModuleBase: Display: XeFG SDK version: 1.2.2, vendor: AMD, RHI: D3D12
01b4:trace:amdxc:AmdExtD3DCreateInterface outer 000000001E7C0080, iid {b58d6601-7401-4234-8180-6febfc0e484c}, obj 0000000032599F78
01b4:trace:amdxc:AmdExtD3DCreateInterface FSR 4 supported: 1
01b4:trace:amdxc:AMDFSR4FFX_UpdateFfxApiProvider 0000000007DC9FC0 0000000032599DC0 80
01b4:trace:loaddll:build_module Loaded L"G:\\home\\user\\titan_quest_ii\\TQ2\\Binaries\\Win64\\amdxcffx64.dll" at 00006FFFEC1A0000: native
01b4:trace:amdxc:AMDFSR4FFX_UpdateFfxApiProvider status: 0
01b4:trace:amdxc:dump_provider returned provider: 2 10000 "4.1.0 *"
01b4:trace:amdxc:AmdExtD3DCreateInterface outer 000000001E7C0080, iid {014937ec-9288-446f-a9ac-d75a8e3a984f}, obj 0000000032599B70
01b4:trace:amdxc:AmdExtD3DFactory_CreateInterface 00000000160D9C80 000000001E7C0080 {f714e11a-b54e-4e0f-abc5-df58b18133d1} 0000000032599B80
01b4:trace:amdxc:AmdExtD3DFactory_CreateInterface FSR 4 supported: 1
[...]

We have loaded the pre-release FSR4 4.1.0 amdxcffx64.dll!

So TL;DR, the Proton amdxc64.dll shim will only load amdxcffx64.dll when setting FSR4_UPGRADE=1, otherwise it falls back to the upscaler DLL. The fall-back path is quite handy to have, and in most cases is actually the preferred path. Particularly when wanting to use the int8 FSR4 algorithm that is only available in the lonewolf upscaler DLL.

So to reiterate:

  1. To perform FSR4 upgrade using the FSR4 algorithm contained in the amdxcffx64.dll, the amdxc64.dll requires envvar FSR4_UPGRADE=1 to be set.
  2. When this envvar is not present, the amdxc64.dll shim falls back to the upscaler DLL ( amd_fidelityfx_upscaler_dx12.dll) and uses it for the FSR4 upgrade.

This mechanic allows one to use the Redstone fp8 4.0.3 upscaler or the recent fp8 4.0.3 amdxcffx64.dll from the latest Windows driver, use the leaked fp8 4.1.0 amdxcffx64.dll, or the int8 4.0.2 upscaler DLL for FSR4 upgrade of any FSR3.1 game on Linux. And this works with both Wine and Proton, but only proton ships the amdxc64.dll shim required for this all to work.

Mystery solved.


EDIT: If anyone is curious, you can see how Proton actually orchestrates the FSR4 upgrade by looking inside the upscalers.py file located in the protonfixes directory.

And here is FSR4 4.1.0:

The cake has yet to bake with this one. Lots of flickering and honestly it is a downgrade over int8 4.0.2 and fp8 4.0.3 in visual quality with no improvement over fp8 4.0.3 in FPS.

Ultra Performance, same settings as my earlier FPS comparison between int8 and fp8 algorithms.



FSR4 Upgrade for Dummies

So we can conclude that the FSR4 upgrade is mildly complicated since RDNA2, RNDA3 and RDNA4 require specific DLLs and envvars for the FSR4 upgrade to work:

RDNA2+ with int8

Requires amdxc64.dll and the int8 4.0.2 upscaler DLL (amd_fidelityfx_upscaler_dx12.dll) and works with any version of vkd3d-proton >= 3.0.

RDNA3 with fp8 (using fp8 on fp16 emulation)

Requires amdxc64.dll, vkd3d-proton to be built with -Denable_extended_emulation and have DXIL_SPIRV_CONFIG=wmma_rdna3_workaround envvar set.

RDNA4 with fp8

Only requires amdxc64.dll and works with any version of vkd3d-proton >= 3.0.

This isn’t even my final form.

Additionally, there are two paths that the “FSR4 upgrade” can be performed:

  1. amd_fidelityfx_upscaler_dx12.dll

This is the default path if the amdxc64.dll is loaded but the FSR4_UPGRADE=1 envvar is not present. To change FSR4 versions, the game’s upscaler and framegeneration DLLs must be replaced. This is the only way to use the int8 FSR4 algorithm, either by a native FSR4 game or through the FSR4 upgrade for FSR3.1 games. (It is possible that my idea of symlinking to the upscaler DLL with ln -s amd_fidelityfx_upscaler_dx12.dll amdxcffx64.dll may work since we know the amdxc64.dll can already do the upgrade with the upscaler DLL directly. But I haven’t tested this method yet. I should point out that this would only work for upgrading the upscaler and break if you tried also upgrading the frame generation, since it is a separate DLL.)

  1. amdxcffx64.dll

This is the intended upgrade path and requires FSR4_UPGRADE=1 to be present. This does not require updating the game’s FSR DLLs (amd_fidelityfx_upscaler_dx12.dll and amd_fidelityfx_framegeneration_dx12.dll). Instead, we update amdxcffx64.dll to get newer FSR4 versions (for both scaler and framegeneration). This DLL needs to be placed next to either the game binary or the amdxc64.dll to be loaded.

Note: When using normal Wine, the only way to turn off the FSR4 upgrade is to use a DLL override (WINEDLLOVERRIDES="amdxc64=d") or to rename or remove the amdxc64.dll from the game directory or the Wine system32 directory. Setting FSR4_UPGRADE=0 has the same behavior as no envvar and will switch to using the upscaler DLL for the upgrade.


EDIT:

I forgot to mention that you can enable FSR4 frame generation as well with an envvar.

#required for vkd3d-proton (built with -Denable_extended_emulation) to enable emulation of fp8 on RDNA3
export DXIL_SPIRV_CONFIG=wmma_rdna3_workaround

#load amdxcffx64.dll for FSR4 upgrade, but as noted, it is not actually required for FSR4 upgrade to work
export FSR4_UPGRADE=1

#prints an overlay at the top left corner with a few details about the active FSR4 upscaler algorithm
export FSR4_WATERMARK=1

#enables using the newer FSR4 frame generation, otherwise you are still using FSR3 FG
export MLFG_UPGRADE=1

#similar to the other overlay, prints a few details about the active FSR4 FG algorithm
export MLFG_WATERMARK=1

The MLFG_* and *_WATERMARK envvars will likely only work with the amdxc64.dll from proton-ge-custom, so I would suggest extracting it from one of the pre-built packages provided on the releases tab. You can also get vkd3d-proton d3d12.dll and d3d12core.dll files built with the -Denable_extended_emulation option, for using fp8 FSR4 upscaler DLLs with RDNA3, from this same package while your are at it.

Thanks!
After being dumb for half a day (to be fair I actually had to work in the same time), I finally manage do apply your guide to make build-in cahyos-proton-slr to work with FSR4 on 7700S with Manor Lords and OptiScaler DLSS spoofing.

As a side-note, Manor Lords do have some FSR support, but I’m not sure if they ever updated to FSR3. At least OptiScaler does not detect upscaler to override when I select FSR, but does work for XeSS and DLSS.

  • So, first I did a single run with PROTON_FSR4_RDNA3_UPGRADE=1 and OptiScaler fgmod scirpt ~/.local/share/goverlay/fgmod/fgmod which installs with goverlay. From what I understand first gives me shim amdxc64.dll and amdxcffx64.dll and second is just easiest way to add OptiScaler to game.

  • Started the game and checked that FSR4.0.2 works.

  • I removed fgmod script because it’s not needed anymore. Honestly it seems to be enough for any sane person. At least for Manor Lords I do not see any difference.

  • Next I replaced PROTON_FSR4_RDNA3_UPGRADE=1 with DXIL_SPIRV_CONFIG=wmma_rdna3_workaround. It seems that if I don’t do that, then cachyos proton (script?) overrides amdxc64.dll and amdxcffx64.dll shims.

  • Then, I downloaded libraries for SDK 2.1.0. Needed .dll files are in Kits/FidelityFx/signedbin.

  • Next, I’m renamed amd_fidelityfx_loader_dx12.dll to amd_fidelityfx_dx12.dll and put it, amd_fidelityfx_upscaler_dx12.dll and amd_fidelityfx_framegeneration_dx12.dll into game’s folder after renaming libraries installed my OptiScaler.

  • Last thing I need is fitting amdxcffx64.dll for which I just downloaded latest (25th of Feb) version from https://download.amd.com/dir/bin/amdxcffx64.dll/. I suspect without using OptiScaler it would not work. upd: this seems to be not necessary

  • Then I’m finding game’s prefix in /steamapps/compatdata/ and there in drive_c/windows/system32/ I’m replacing amdxcffx64.dll with downloaded version.

Now just launched and started the game, opened OptiScaler and changing upscaler to FSR3+ showed me FSR4.0.3

Didn’t test MFG, because it never looked good for me. I actually not that excited about upscalers either, but what can you do, where there are no better AA options in most games anymore. :sweat_smile:

Didn’t test MFG, because it never looked good for me. I actually not that excited about upscalers either, but what can you do, where there are no better AA options in most games anymore. :sweat_smile:

I feel the exact same way for both the use of upscalers and frame generation. Frame generation is just fake frames to pad the display refresh rate. And in doing so, it can help make cursor movement smoother (when capped by the game’s frame rate), but the actual game play doesn’t really feel smoother. So, yeah. I leave it turned off too. I’m also not a big fan of UE5 being basically built around upscaling and most games, but not all, don’t even have the option to turn them off and run natively.

I suspect without using OptiScaler it would not work.

If the game targets amd_fidelityfx_dx12.dll then it is not a candidate for FSR4 upgrade from my testing and OptiScaler is needed to get it to work. Any game that targets the split FidelityFX DLLs ( amd_fidelityfx_upscaler_dx12.dll and amd_fidelityfx_framegeneration_dx12.dll) will enable FSR4 with the upscaler DLL through amdxc64.dll when present. Or, if FSR4_UPGRADE=1 is set and amdxcffx64.dll is present, then amdxcffx64.dll is used instead of the upscaler DLL ( amd_fidelityfx_upscaler_dx12.dll).

To really check what API is being used you need to set FSR4_WATERMARK=1 and look at the “BUILD TIME” and the “MLSR UPSCALE” values. WMMA is the fp8 FSR4 algorithm, while v07-i8 is the int8 FSR4 algorithm. I’m not sure if this envvar will work with OptiScaler though, since I haven’t done any testing with OptiScaler yet.

Do note that the int8 FSR 4.0.2 DLL gets about 12% higher FPS than any fp8 FSR4 version when running on RDNA3 from my testing.

The int8 FSR 4.0.2 DLL made Clair Obscur much more playable for me. Both FSR3 and Xess had weird upscaler artifacts / noise that really annoyed me. Switching to FSR4 though made the hair and other fine details much more stable and the game looks really good now. But FSR4 has less overall FPS than ether Xess or FSR3 and this is where the int8 algorithm shines over fp8 on weaker RDNA3 HW.

I’ve never used goverlay, but I have been meaning to play around with OptiScaler. I’ll give it a go with Hell Is Us, which targets amd_fidelityfx_dx12.dll and thus doesn’t currently work with the FSR4 upgrade implemented by the Proton amdxc64.dll shim.

amdxcffx64.dll for which I just downloaded latest (25th of Feb) version from https://download.amd.com/dir/bin/amdxcffx64.dll/

Nice! I didn’t notice AMD updated the available amdxcfxx64.dll files.

When looking at that new DLL from 25-Feb-2026 20:42, it doesn’t actually show that it is FSR4 4.0.3… Hmmm. And looking at the actual size of the file, this does not have the new framegeneration (makes the DLL huge). I think this is a rebuild of 4.0.0 and you have to still extract the 4.0.3 amdxcffx64.dll from AMD’s Windows driver.

Yeah, I would not recommend using this DLL.

01c4:trace:amdxc:AMDFSR4FFX_UpdateFfxApiProvider 00007F536283C520 00007F52FFFD9EF0 80
01c4:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\amdxcffx64.dll" at 00006FFFEB660000: native
01c4:trace:amdxc:AMDFSR4FFX_UpdateFfxApiProvider status: 80070057
01c4:trace:amdxc:dump_provider returned provider: 2 10000 "\x04"

Which is older than the upscaler DLL included with TQ2 and apparently, amdxc64.dll will go with the highest provider version (2 10002 "" over 2 10000 "\x04"). So it never actually loaded the FSR4 code from the recent amdxcffx64.dll uploaded to AMD’s website on 25-Feb-2026 20:42.

Apparently, and I have noticed this behavior, but have not mentioned it until now, if the upscaler DLL has a newer FSR4 version, it will be used over the amdxcffx64.dll even if FSR4_UPGRADE=1 is set and amdxcffx64.dll is loaded.

This is the default FidelityFX upscaler DLL that ships with TQ2 pre-release. So the “new” amdxcffx64.dll from AMD’s website loaded, but wasn’t used because the game ships with a slightly newer build from FidelityFX SDK 2.0.0.

01e8:trace:amdxc:AMDFSR4FFX_UpdateFfxApiProvider 00007F536283C520 00007F52E5C5F9C0 80
01e8:trace:amdxc:AMDFSR4FFX_UpdateFfxApiProvider status: 80070057
01e8:trace:amdxc:dump_provider returned provider: 2 10002 ""


EDIT: Here is with the 4.0.3 amdxcffx64.dll taken from the Windows driver dated Feb 25 2026:

01cc:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\amdxcffx64.dll" at 00006FFFE9050000: native
01cc:trace:amdxc:AMDFSR4FFX_UpdateFfxApiProvider status: 0
01cc:trace:amdxc:dump_provider returned provider: 2 10000 "4.0.3 *"

Note that the build date is older than the FidelityFX SDK 2.1.0 (or the 2.1.1 re-release) upscaler DLL’s FSR4 version, dated DEC 9 2025 10:05:35 as shown in a previous post.

And another one bites the dust. PSA edition.

So, things are even clearer now. (And more nuanced than before.)

  1. FSR4_UPGRADE=1 tells the amdxc64.dll shim to load amdxcffx64.dll. Nothing more.

  2. The “FSR4 upgrade” is done based on versioning of the FSR4 code contained in both the amd_fidelityfx_upscaler_dx12.dll and amdxcffx64.dll files. Whichever file has the newest “BUILD TIME” is picked to perform the upgrade.

This means that even if you use FSR4_UPGRADE=1 and place amdxcffx64.dll next to amdxc64.dll it may not actually get used. The FSR4 upgrade will still work, but the upscaler DLL (amd_fidelityfx_upscaler_dx12.dll) will be used instead.

So if you want to force the use of a particular amdxcffx64.dll, you have to use an amd_fidelityfx_upscaler_dx12.dll with an older “BUILD TIME” to do so.

Another mystery solved.

here is what I get with enabling watermark

As I understand that does correlate with version higher then 4.0.2
I guess that all means that I could just not bother with replacing amdxcffx64.dll?

Interesting that when I tried to use PROTON_FSR4_RDNA3_UPGRADE=1 I kept getting same 4.0.2 version. Might be that i was doing something else differently, but I’m not sure right now.

This is the version I get in SM2 with just PROTON_FSR4_RDNA3_UPGRADE=1 (curious that it’s affected by some post-processing)