[Question] Control and the DirectX 12 on the Steam Deck - eviltoast

Just to be clear, the game runs great with the DX11 on my Steam Deck Oled. The only downside is that i find out that you can actually enable HDR by following this guide and it works GREAT… until it doesn’t. The guide itself work with no issue but to enable the hdr option I have to run the game with DX12, and dx12 ( tested with or without mods) cause some random drop to 1 fps in some point of the map, usually in the space between rooms. I tried both Proton Experimental, and GE Proton but the lags keep happening. Anyone have a fix to that?

  • Skull giver@popplesburger.hilciferous.nl
    link
    fedilink
    arrow-up
    22
    ·
    edit-2
    10 months ago

    TL;DR: Shader recompilation sucks, but it’s inevitable; it’s how you can play DirectX games on Linux.

    Shaders describe how to render stuff. The game feeds the GPU some shader code and a list of points, and shaders get used to turn those points into triangles, and those triangles get turned into filled shapes that are rendered to the screen. The triangles themselves are quite to translate back and forth (I’m pretty sure all you need to do is invert the Z-axis because Microsoft chose a different default coordinate system), but that’s not as easy with the shader code.

    Linux, Windows, and various consoles can use Vulkan to do graphics; it’s basically an open DirectX alternative (it’s more complicated than that but let’s just pretend it is). Vulkan uses a completely different type of GPU code that will get translated to about the same code that ends up being executed, but the intermediate storage that the game interacts with is different.

    This is where shader recompilation comes in: the DirectX shaders get intercepted when the game tries to run them, much like how requests to open and read files are intercepted and turned into Linux operations, and the code gets ripped apart, interpreted, and rebuilt into shaders that can be used by the Vulkan graphics code. The game doesn’t know this is happening because the recompilation makes it seem like the game is running on real DirectX.

    Because this reinterpretation takes a bunch of processing power and halts the game if it doesn’t happen during a loading screen (which is the case in most modern games), the result of this recompilation gets saved to disk, assuming there’s space. Next time the game is trying to load the shaders that were already processed, it loads them from the SSD rather than doing the hard work again, basically making the translation instantaneously.

    Fun fact: early versions of Elden Ring shipped with a bug that caused the shaders to get loaded over and over again in some cases, causing frame drops and slowdowns on Windows, but Linux players were barely affected because that stuff is basically the norm on DXVK and the runtime was already optimized for it.

    This shader recompilation step happens on all kinds of GPU-code-to-GPU-code translation software (DXVK on Linux, but also on console emulators like Dolphin, and more). Steam fixes most of this problem by doing the recompilation on their side, storing the results, and having the Deck download the precompiled shader caches with games. That’s why there’s an extra download step for Steam games on Linux, and why games take up more space than on Windows. However, but you can’t use Steam’s DX11 shader caches with DX12, and I believe Steam only precompiles the DX11 caches.

    A theoretical fix would be to download the shader caches from someone else who already went through the entire game with your patches applied. Unfortunately, sharing shader caches is not something I’ve seen outside of the Dolphin community. In some circumstances, you can tell the computer to generate all of these caches in bulk outside of the game so you can play smoothly, but I’m not sure if this is available in PC games.

    I’m not sure what the patch changes exactly, so it’s hard to say what the exact problem is. Normally, recompiled shaders are cached on the file system so that they’ll be loaded instantly the next time they’re used, and the frame drop should only occur when you’re loading large new areas which requires loading new shader code. If you’re seeing slowdowns every time you go through previous areas, it could be that the modifications cause problems with the shader cache, in which case the shader recompilation needs to take place every time. If you only get slowdowns for new areas/enemies/objects/animations, then the system is probably Working As Intended and I don’t think there are any workarounds.

    The only alternative to shader recompilation system would be Microsoft porting DirectX to Linux, but that’s never ever going to happen.