Earlier this week, news broke of a modder that hacked AMD’s FSR 2.0 temporal upscaling technology into Cyberpunk 2077, allowing users of non-RTX graphics cards the chance to play the game at higher frame-rates with substantially better visual quality than with FSR 1.0 upscaling. That’s massive for owners of AMD GPUs, and the mod even works beautifully on Steam Deck.
We contacted the mod’s creator, the gloriously named PotatoOfDoom1337, to find out exactly how it works – and whether it means that FSR 2.0 will soon be available in a tonne of existing games. Here’s the interview, edited lightly for clarity. Enjoy!
What’s your background in programming and game modding? On NexusMods, it looks like you’ve only been creating mods since April last year?
PotatoOfDoom: I am studying computer science, have always been interested in the technical aspect of video games and was fascinated when I learned about projects like Reshade, Special K or DXVK. I see programming as my favorite hobby and additionally like reverse engineering and messing around with code a lot. I made my first Cyberpunk 2077 mod because CDPR fixed a very fun bug in the game. This annoyed me so much that I downloaded the development tools and re-implemented the bug myself. The process of creating this mod got me hooked, I learned more about the game over time and started creating more complex mods.
What motivated you to try to hack FSR 2.0 into Cyberpunk 2077?
PotatoOfDoom: Mainly my aging GTX 1080, a bit of envy towards RTX users because of their exclusive DLSS technology, and curiosity about how temporary upscaling solutions work in general. Also, FSR 2.0 and DLSS were described as being very similar, so I just wanted to see if it was possible.
How did you develop the mod?
PotatoOfDoom: I initially started the mod a few weeks ago in anticipation of the FSR 2.0 open source release. The first steps were to get the game talk to my custom .dll and tell the game that it supports DLSS and report the available DLSS resolutions to the game by implementing the required interfaces. Then I wrote a small shader that just displays a blank red image. My goal was to use this as a base to verify that the DirectX parts of my code were working correctly. Then I just waited for the open source release. After AMD released the source code, I immediately replaced my test code with FSR 2.0. I expected to work on it for several days, but was pleasantly surprised that it only took me a few hours to integrate. I used debuggers like x64dbg and reverse engineering software like IDA and Ghidra to find the specifics of the DLSS behavior in the game code. Also, for debugging the buffers, RenderDoc was incredibly helpful.
Were there any surprises in terms of things being harder or easier to accomplish?
PotatoOfDoom: The main DLSS and FSR input buffers are the same. I basically just copied the FSR integration from the AMD example, set the FoV/Depth values, launched the game and immediately got a pretty decent image. The worst thing was a quirk in Cyberpunk where the game wouldn’t reset a special DirectX structure (ComputeRootSignature) after running DLSS. This is not so important for Nvidia’s DLSS since it uses CUDA, but unfortunately FSR uses ordinary DirectX compute shaders, which break the game. So I had to find a way to restore that structure after running FSR.
In terms of the FSR 2.0 CP2077 implementation, what is working well at the moment and what needs to be fixed?
PotatoOfDoom: Ghosting and animated textures are the biggest problems right now. Both DLSS and FSR use separate masks to give the algorithm hints about whether to reuse old temporal material or discard it, but they don’t seem to be compatible and I need to create a shader that translates the DLSS masks into FSR masks.
DLSS and FSR masks… are they similar to a Photoshop mask?
PotatoOfDoom: Yeah, basically like that. You can imagine them as a greyscale image with values ranging from 0.0 to 1.0 and the temporal upscaler reprojects old frames depending on those values. The FSR documentation goes into more in detail about that.