Nukem9 / dlssg-to-fsr3

Adds AMD FSR 3 Frame Generation to games by replacing Nvidia DLSS-G Frame Generation (nvngx_dlssg).
GNU General Public License v3.0
4.22k stars 157 forks source link

How to get this working on linux #93

Open NielsVandenEynde opened 8 months ago

NielsVandenEynde commented 8 months ago

Is there a way to get this working on linux? Right now it won't work even with adding the .reg files and using winedlloverrides

Marjaperse commented 8 months ago

DLSS FG doesn't work on Linux, so I doubt this will either. Your hope is for native FSR3 mods. Not FSR3 through DLSS3 FG

Saancreed commented 8 months ago

Wine currently does not support the APIs Streamline uses to check if Hardware Accelerated GPU Scheduling is enabled. I have a hack for this here which should apply to Wine 9.0-rc2 and some flavors of it.

Warning though, some assembly is required; you will need to compile your own Wine to use this. It seems to be working for me in Cyberpunk 2077 (you will need to export WINEHAGS=1 environment variable to enable it).

Weather-OS commented 8 months ago

For those who are having linker issues with @Saancreed's Wine HAGS Patch, You need to add the line SYSCALL_ENTRY( 0x0191, NtGdiDdDDIEnumAdapters2, 4) to the end of a/dlls/win32u/win32syscalls.h

Saancreed commented 8 months ago

@Weather-OS I wouldn't recommend modifying that file manually, it should be regenerated by running tools/make_specfiles before building.

Also, here's a bonus screenshot: Screenshot_20231220_113106

Weather-OS commented 8 months ago

@Saancreed I'm tryna get it working for Proton though I haven't had much success yet.

Weather-OS commented 8 months ago

I'm also having another issue here, I can't get this to work because of this: warn: DXGI: Found monitors not associated with any adapter, using fallback

Saancreed commented 8 months ago

It's probably caused by some GPUs being hidden from the application, but that shouldn't be a problem, Streamline only cares about adapters and not outputs/monitors/displays. I have the same warning being printed over here and HAGS check still succeeds.

Weather-OS commented 8 months ago

As a Consequence, I can't enable DLSS. Also even with WINEHAGS=1, The game still complains: result:Result::eErrorOSDisabledHWS so I can't enable DLSS FG either

Weather-OS commented 8 months ago

I can do something here though, Since Streamline is open source, can't I just remove the check from there?

Saancreed commented 8 months ago

IIRC in production/release builds Streamline checks if plugins are signed by Nvidia before loading them, so it will probably refuse to load your own self-compiled binary.

Weather-OS commented 8 months ago

I tried before, you can use sigthief and it will work just fine. The issue is that some games have their own custom implementations for it.

Weather-OS commented 8 months ago

@Saancreed Is there like no way to fix the DXGI Error? After testing, the only game that worked was Cyberpunk. Every other game that supported DLSS FG that I threw at it just refused to function. Not only that, DLSS Upscaling was also disabled for whatever reason.

Saancreed commented 8 months ago

Is there like no way to fix the DXGI Error?

It's not an error, it just means that your display is connected to some adapter that can't be found so it will be reported as connected to another GPU. Streamline should not care about this, only that there is some adapter for which the LUID matches with Nvidia one used by the game.

After testing, the only game that worked was Cyberpunk. Every other game that supported DLSS FG that I threw at it just refused to function.

The only other DLSS-FG game I'm running directly with Wine is Diablo IV where it also allowed me to enable Frame Generation.

Anyway, here is a simple program to check the same thing as Streamline does, compile it and run in your Wine prefix to see what is actually reported to the game:

#include <windows.h>
#include <winternl.h>
#include <ddk/d3dkmthk.h>

#include <cstdint>
#include <iostream>
#include <vector>

extern "C" NTSTATUS WINAPI D3DKMTQueryAdapterInfo(D3DKMT_QUERYADAPTERINFO *desc);

int main()
{
    D3DKMT_ENUMADAPTERS2 enumAdapters{};
    enumAdapters.NumAdapters = 0;
    enumAdapters.pAdapters = nullptr;

    if (!NT_SUCCESS(D3DKMTEnumAdapters2(&enumAdapters)))
        return 1;

    std::cout << "Adapters count: " << enumAdapters.NumAdapters << std::endl;

    std::vector<D3DKMT_ADAPTERINFO> adapterInfo;
    adapterInfo.resize(enumAdapters.NumAdapters);
    enumAdapters.pAdapters = adapterInfo.data();

    if (!NT_SUCCESS(D3DKMTEnumAdapters2(&enumAdapters)))
        return 1;

    for (uint32_t i = 0; i < enumAdapters.NumAdapters; i++)
    {
        const auto& adapter = adapterInfo[i];

        std::cout << "Adapter: " << i << std::endl;
        std::cout << "LUID: " << std::hex << adapter.AdapterLuid.HighPart << ' ' << adapter.AdapterLuid.LowPart << std::endl;

        D3DKMT_WDDM_2_7_CAPS data{};
        D3DKMT_QUERYADAPTERINFO info{};
        info.hAdapter = adapter.hAdapter;
        info.Type = KMTQAITYPE_WDDM_2_7_CAPS;
        info.pPrivateDriverData = &data;
        info.PrivateDriverDataSize = sizeof(data);

        if (NT_SUCCESS(D3DKMTQueryAdapterInfo(&info)))
            std::cout << "HwSchEnabled: " << data.HwSchEnabled << std::endl;
    }
}

Compiled with wineg++ -lgdi32 this prints for me:

$ WINEHAGS=1 WINEDEBUG=-all wine64 ./main.exe.so 
wine: using fast synchronization.
Adapters count: 2
Adapter: 0
LUID: 0 3f4
HwSchEnabled: 1
Adapter: 1
LUID: 0 3f5
HwSchEnabled: 1

Which correspond to DXGI adapters mapped from my Vulkan physical devices:

$ WINEDEBUG=-all wine64 ./vulkaninfo-x64.exe | grep --after=7 -E 'VkPhysicalDevice(ID)?Properties:'
…
VkPhysicalDeviceProperties:
---------------------------
        apiVersion        = 1.3.267 (4206859)
        driverVersion     = 23.3.1 (96481281)
        vendorID          = 0x8086
        deviceID          = 0xa788
        deviceType        = PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU
        deviceName        = Intel(R) Graphics (RPL-S)
--
VkPhysicalDeviceIDProperties:
-----------------------------
        deviceUUID      = 868088a7-0400-0000-0002-000000000000
        driverUUID      = b4b68806-df7f-0ed9-988d-117727c5596b
        deviceLUID      = f4030000-00000000
        deviceNodeMask  = 1
        deviceLUIDValid = true

--
VkPhysicalDeviceProperties:
---------------------------
        apiVersion        = 1.3.260 (4206852)
        driverVersion     = 545.29.6.0 (2286371200)
        vendorID          = 0x10de
        deviceID          = 0x27e0
        deviceType        = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
        deviceName        = NVIDIA GeForce RTX 4080 Laptop GPU
--
VkPhysicalDeviceIDProperties:
-----------------------------
        deviceUUID      = d68a9313-2549-28b6-c068-30558bc4b489
        driverUUID      = 468717c2-5245-5d6d-9401-72b8a4ff98e5
        deviceLUID      = f5030000-00000000
        deviceNodeMask  = 1
        deviceLUIDValid = true

So, any game that uses my RTX 4080 Mobile will search for a D3DKMT adapter with LUID 03f5, find one as returned by the API my hack implemented and be convinced that HAGS is enabled.

Weather-OS commented 8 months ago

Alright so I managed to fix the DXGI warning and now I can use DLSS. But still, the game is complaining that Hardware scheduling is disabled. Do I need a specific build of sl.interposer.dll?

Weather-OS commented 8 months ago

Oh I'm such an idiot. I forgot to add the second patch.

MichaelGoodale commented 8 months ago

Hey, I managed to get this working on Proton by patching proton-tkg with Wine 9.0rc2 and it works! I get frame generation and everything. However, when frame gen is on, the entire game gets rendered with a grisly red hue that makes the game totally unplayable. Anyone else seen this or something like it before?

Weather-OS commented 8 months ago

Having the same issue here. It looks like FB CM Corruption. Also FG Technically doesn't get enabled either. it's extremely weird. If your game internally checks for Reflex support (You can't bypass this even with LatencyFleX), it may disable FG internally as well, which makes the FG option placebo or it may disable it entirely (like in the case with R&C Rift Apart). You may force FG By modifying your game's binary though I wouldn't recommend it. Some games I tested required this modification, Almost every game I tested except for Cyberpunk for whatever reason resulted in this pinkish or red-ish hue with FG not working entirely.

Weather-OS commented 8 months ago

@MichaelGoodale For the time being, use this mod in a QEMU/KVM Setup. I may also look into fixing some of the issues it has.

MichaelGoodale commented 8 months ago

Hmmm, very odd indeed! It looked as though I had FG, Mangohud reported higher frames but perhaps that was a mistake. I swear it looked more fluid though. Odder still, the game that had this hue for me was Cyberpunk!

Saancreed commented 8 months ago

If your game internally checks for Reflex support (You can't bypass this even with LatencyFleX)

Don't try to bypass it then, use Nvidia's patches for full Reflex support via VK_NV_low_latency2 Vulkan extension. They would need some rebasing for latest vkd3d-proton (and Vulkan-Headers if you're on NV 545.29.06 driver because it supports only spec 2 version of that ext) but they are actually usable.

With actual Reflex added to the mix, it becomes possible to also test Frame Generation in some simpler applications like Path Tracing SDK sample. Again, that sample works for me with correct colors.

Odder still, the game that had this hue for me was Cyberpunk!

Welp, I've seen this over at https://github.com/ValveSoftware/Proton/issues/7361. Unfortunately, I don't think anyone knows what's causing this still.

MrDuartePT commented 8 months ago

It also happen on The Witcher 3 New Gen update as well.

giantplaceholder commented 8 months ago

Do read https://github.com/ValveSoftware/Proton/issues/7361#issuecomment-1872316211 and the messages after to handle the pinkish tint issue.