diff --git a/README.md b/README.md
index e50a606e8..7e0447843 100644
--- a/README.md
+++ b/README.md
@@ -124,6 +124,32 @@ If you are planning to contribute or just want to learn more about this project
The emulator has settings for enabling or disabling some logging, remapping controllers, and more.
You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the Ryujinx data folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
+## Beast Roofer Edition — graphics extras / extras graphiques
+
+### 🇬🇧 Native TAA (Temporal Anti-Aliasing)
+Available in **Settings > Graphics > Anti-Aliasing > TAA**. Soft, cinematic, low-flicker image; works on **all GPUs** with no extra files. It looks best at higher internal resolution scales; at low resolution it may flicker a little more.
+
+### 🇫🇷 TAA natif (anti-crénelage temporel)
+Disponible dans **Paramètres > Graphismes > Anti-crénelage > TAA**. Rendu doux, cinématographique, peu de scintillement ; fonctionne sur **toutes les cartes graphiques**, aucun fichier à ajouter. Meilleur en haute résolution interne ; peut scintiller un peu plus en basse résolution.
+
+### 🇬🇧 NVIDIA DLSS / DLAA (experimental, RTX only, opt-in)
+DLSS/DLAA is **off by default** and **experimental**. No NVIDIA files are bundled (legal reasons). To enable it:
+1. Create a folder named **`dlss`** next to **`Ryujinx.exe`**.
+2. Put the **NVIDIA Streamline** files in it: `sl.interposer.dll`, `sl.common.dll`, `sl.dlss.dll` (MIT-licensed; from the public Streamline SDK).
+3. The DLSS runtime (`nvngx_dlss.dll`) is **located automatically** from your own installed games/driver. If it isn't found, drop your own copy into the same `dlss` folder.
+4. In **Settings > Graphics**, set the **Scaling Filter** to **DLSS** and pick a mode (**DLAA** is the most stable). Applies on the next launch (the app restarts).
+
+⚠️ Experimental: may be unstable depending on the game/GPU. With no `dlss` folder or no DLSS file present, DLSS simply stays unavailable (no crash). Requires a recent NVIDIA RTX GPU.
+
+### 🇫🇷 NVIDIA DLSS / DLAA (expérimental, RTX uniquement, optionnel)
+DLSS/DLAA est **désactivé par défaut** et **expérimental**. Aucun fichier NVIDIA n'est inclus (raisons légales). Pour l'activer :
+1. Crée un dossier nommé **`dlss`** à côté de **`Ryujinx.exe`**.
+2. Mets-y les fichiers **NVIDIA Streamline** : `sl.interposer.dll`, `sl.common.dll`, `sl.dlss.dll` (sous licence MIT ; du SDK Streamline public).
+3. Le runtime DLSS (`nvngx_dlss.dll`) est **localisé automatiquement** depuis tes propres jeux/pilote installés. S'il n'est pas trouvé, dépose ta propre copie dans le même dossier `dlss`.
+4. Dans **Paramètres > Graphismes**, mets le **Filtre de mise à l'échelle** sur **DLSS** et choisis un mode (**DLAA** = le plus stable). S'applique au prochain lancement (l'app redémarre).
+
+⚠️ Expérimental : peut être instable selon le jeu/la carte. Sans dossier `dlss` ou sans fichier DLSS, DLSS reste simplement indisponible (pas de plantage). Nécessite une carte NVIDIA RTX récente.
+
## License
This software is licensed under the terms of the [MIT license](https://git.ryujinx.app/projects/Ryubing/src/branch/master/LICENSE.txt).
@@ -136,3 +162,10 @@ See [LICENSE.txt](https://git.ryujinx.app/projects/Ryubing/src/branch/master/LIC
- [AmiiboAPI](https://www.amiiboapi.com) is used in our Amiibo emulation.
- [ldn_mitm](https://github.com/spacemeowx2/ldn_mitm) is used for one of our available multiplayer modes.
- [ShellLink](https://github.com/securifybv/ShellLink) is used for Windows shortcut generation.
+
+### Beast Roofer Edition
+
+- **Original code in this fork** by **The Roofer Dev** (© 2026), MIT-licensed: native TAA, clean-room NVIDIA DLSS/DLAA/NIS integration, native scRGB HDR, per-game VRR cap. *Code/integration only — DLSS, DLAA and NIS technologies belong to NVIDIA.*
+- **🇫🇷 Code original de ce fork** par **The Roofer Dev** (© 2026), sous licence MIT : intégration du TAA natif, intégration clean-room de NVIDIA DLSS/DLAA/NIS, HDR scRGB natif, cap VRR par jeu. *Code/intégration uniquement — les technologies DLSS, DLAA et NIS appartiennent à NVIDIA.*
+- This fork bundles **no proprietary NVIDIA files**. [NVIDIA Streamline](https://github.com/NVIDIA-RTX/Streamline) and NVIDIA Image Scaling (NIS) are MIT-licensed (© NVIDIA). The DLSS runtime (`nvngx`) is proprietary and **never bundled** — it is located on the user's own machine.
+- NVIDIA, DLSS, DLAA and NIS are trademarks of NVIDIA Corporation. This is an independent project, **not affiliated with or endorsed by NVIDIA**.
diff --git a/distribution/legal/THIRDPARTY.md b/distribution/legal/THIRDPARTY.md
index 5caa03771..5277ac3b9 100644
--- a/distribution/legal/THIRDPARTY.md
+++ b/distribution/legal/THIRDPARTY.md
@@ -711,3 +711,61 @@
SOFTWARE.
```
+
+# NVIDIA Image Scaling - NIS (MIT)
+
+ See License
+
+ ```
+ The MIT License (MIT)
+
+ Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+ ```
+
+
+# NVIDIA Streamline (MIT)
+
+ See License
+
+ ```
+ The MIT License (MIT)
+
+ Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+ ```
+
diff --git a/src/Ryujinx.Common/Configuration/AntiAliasing.cs b/src/Ryujinx.Common/Configuration/AntiAliasing.cs
index 1510c23ee..f6cdc39f9 100644
--- a/src/Ryujinx.Common/Configuration/AntiAliasing.cs
+++ b/src/Ryujinx.Common/Configuration/AntiAliasing.cs
@@ -11,5 +11,6 @@ namespace Ryujinx.Common.Configuration
SmaaMedium,
SmaaHigh,
SmaaUltra,
+ Taa,
}
}
diff --git a/src/Ryujinx.Graphics.GAL/DlssJitterState.cs b/src/Ryujinx.Graphics.GAL/DlssJitterState.cs
new file mode 100644
index 000000000..717683076
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/DlssJitterState.cs
@@ -0,0 +1,32 @@
+namespace Ryujinx.Graphics.GAL
+{
+ ///
+ /// Cross-layer hand-off for DLSS "Mode B" sub-pixel jitter. The DLSS backend generates the Halton
+ /// offset and publishes the NEXT frame's value in /; the GPU
+ /// layer (StateUpdater) reads it to shift the resolution-scaled viewport of the frame it is rendering.
+ ///
+ /// The hard part is handing DLSS the offset the PRESENTED frame was actually rendered with. Matching by
+ /// texture reference failed (the presented framebuffer is a different texture than the jittered 3D
+ /// target), so instead the offset is carried THROUGH the present frame queue: it is snapshotted onto
+ /// each frame when it is enqueued for presentation, then written to / when that exact frame is dequeued and presented. The DLSS backend reads those, so
+ /// the offset always matches the frame on screen regardless of frame-queue depth or frames-in-flight.
+ ///
+ /// When is false the GPU layer skips all of this, so the path is byte-identical.
+ /// This lives in GAL because the GPU layer cannot reference the Vulkan backend.
+ ///
+ public static class DlssJitterState
+ {
+ public static bool Enabled;
+
+ /// The next frame's jitter offset, in internal-render pixels, published by the DLSS backend
+ /// and read by the GPU layer to jitter the scaled viewport.
+ public static float OffsetX;
+ public static float OffsetY;
+
+ /// The jitter offset the frame currently being presented was rendered with. Set by the GPU
+ /// present from the value carried alongside that frame through the queue; read by the DLSS backend.
+ public static float PresentX;
+ public static float PresentY;
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/IWindow.cs b/src/Ryujinx.Graphics.GAL/IWindow.cs
index a364867d1..cee3556e9 100644
--- a/src/Ryujinx.Graphics.GAL/IWindow.cs
+++ b/src/Ryujinx.Graphics.GAL/IWindow.cs
@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.GAL
{
public interface IWindow
{
- void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback);
+ void Present(ITexture texture, ITexture depthTexture, ImageCrop crop, Action swapBuffersCallback);
void SetSize(int width, int height);
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Window/WindowPresentCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Window/WindowPresentCommand.cs
index 4034bc3c6..1d673e0b6 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Window/WindowPresentCommand.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Window/WindowPresentCommand.cs
@@ -8,12 +8,14 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Window
{
public readonly CommandType CommandType => CommandType.WindowPresent;
private TableRef _texture;
+ private TableRef _depthTexture;
private ImageCrop _crop;
private TableRef _swapBuffersCallback;
- public void Set(TableRef texture, ImageCrop crop, TableRef swapBuffersCallback)
+ public void Set(TableRef texture, TableRef depthTexture, ImageCrop crop, TableRef swapBuffersCallback)
{
_texture = texture;
+ _depthTexture = depthTexture;
_crop = crop;
_swapBuffersCallback = swapBuffersCallback;
}
@@ -21,7 +23,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Window
public static void Run(ref WindowPresentCommand command, ThreadedRenderer threaded, IRenderer renderer)
{
threaded.SignalFrame();
- renderer.Window.Present(command._texture.Get(threaded)?.Base, command._crop, command._swapBuffersCallback.Get(threaded));
+ renderer.Window.Present(command._texture.Get(threaded)?.Base, command._depthTexture.Get(threaded)?.Base, command._crop, command._swapBuffersCallback.Get(threaded));
}
}
}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs
index 9d1d23a33..7fa2548a5 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs
@@ -17,13 +17,17 @@ namespace Ryujinx.Graphics.GAL.Multithreading
_impl = impl;
}
- public unsafe void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
+ public unsafe void Present(ITexture texture, ITexture depthTexture, ImageCrop crop, Action swapBuffersCallback)
{
// If there's already a frame in the pipeline, wait for it to be presented first.
// This is a multithread rate limit - we can't be more than one frame behind the command queue.
_renderer.WaitForFrame();
- _renderer.New()->Set(new TableRef(_renderer, texture as ThreadedTexture), crop, new TableRef(_renderer, swapBuffersCallback));
+ _renderer.New()->Set(
+ new TableRef(_renderer, texture as ThreadedTexture),
+ new TableRef(_renderer, depthTexture as ThreadedTexture),
+ crop,
+ new TableRef(_renderer, swapBuffersCallback));
_renderer.QueueCommand();
}
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
index 4f2f01606..c1fe42f5e 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
@@ -739,6 +739,25 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
Span viewportTransformSpan = _state.State.ViewportTransform.AsSpan();
Span viewportExtentsSpan = _state.State.ViewportExtents.AsSpan();
+ // DLSS Mode B: hand the shader this frame's sub-pixel jitter as a clip-space NDC offset, which it
+ // adds to gl_Position scaled by w (the correct, native-DLSS way to jitter -- not a viewport shift).
+ // Only the scaled (main) 3D pass; native passes (UI) keep RenderTargetScale 1 and are NOT jittered.
+ // The offset is 0 unless jitter is enabled, so the default path is unchanged.
+ float jitterNdcX = 0f, jitterNdcY = 0f;
+ if (DlssJitterState.Enabled && _channel.TextureManager.RenderTargetScale != 1f)
+ {
+ ref ViewportTransform vp0 = ref viewportTransformSpan[0];
+ float jScale = _channel.TextureManager.RenderTargetScale;
+ float vpWidth = MathF.Abs(vp0.ScaleX) * 2f * jScale;
+ float vpHeight = MathF.Abs(vp0.ScaleY) * 2f * jScale;
+ if (vpWidth > 0f && vpHeight > 0f)
+ {
+ jitterNdcX = DlssJitterState.OffsetX * 2f / vpWidth;
+ jitterNdcY = DlssJitterState.OffsetY * 2f / vpHeight;
+ }
+ }
+ _context.SupportBufferUpdater.SetJitter(jitterNdcX, jitterNdcY);
+
for (int index = 0; index < Constants.TotalViewports; index++)
{
if (disableTransform)
diff --git a/src/Ryujinx.Graphics.Gpu/GpuContext.cs b/src/Ryujinx.Graphics.Gpu/GpuContext.cs
index 7ee32e83d..1b474904e 100644
--- a/src/Ryujinx.Graphics.Gpu/GpuContext.cs
+++ b/src/Ryujinx.Graphics.Gpu/GpuContext.cs
@@ -46,6 +46,13 @@ namespace Ryujinx.Graphics.Gpu
///
public Window Window { get; }
+ ///
+ /// Most recently bound depth-stencil render target, captured so the presentation path can hand a
+ /// real depth buffer to temporal upscalers (DLSS). May be stale or a UI depth, so consumers must
+ /// validate it (e.g. by dimensions) before use. Written and read on the GPU thread only.
+ ///
+ internal Image.Texture LastPresentDepthStencil { get; set; }
+
///
/// Internal sequence number, used to avoid needless resource data updates
/// in the middle of a command buffer before synchronizations.
diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
index db2921468..89ce6ab13 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
@@ -210,6 +210,13 @@ namespace Ryujinx.Graphics.Gpu.Image
_rtDepthStencil = depthStencil;
}
+ // Publish the last bound depth so the presentation path can forward a real depth buffer to
+ // DLSS. Only non-null binds (a real pass) update it; consumers validate dimensions.
+ if (depthStencil != null)
+ {
+ _context.LastPresentDepthStencil = depthStencil;
+ }
+
return changesScale || ScaleNeedsUpdated(depthStencil);
}
diff --git a/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs b/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs
index da19bd064..b0f2fe84b 100644
--- a/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs
+++ b/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs
@@ -88,6 +88,23 @@ namespace Ryujinx.Graphics.Gpu.Memory
MarkDirty(SupportBuffer.ViewportSizeOffset, SupportBuffer.FieldSize);
}
+ ///
+ /// Sets the DLSS Mode B clip-space jitter offset (in NDC) the shader adds to vertex positions
+ /// (scaled by w). Zero unless jitter is enabled, so the default path is unaffected.
+ ///
+ /// Jitter X in normalized device coordinates
+ /// Jitter Y in normalized device coordinates
+ public void SetJitter(float x, float y)
+ {
+ if (_data.JitterOffset.X != x || _data.JitterOffset.Y != y)
+ {
+ _data.JitterOffset.X = x;
+ _data.JitterOffset.Y = y;
+
+ MarkDirty(SupportBuffer.JitterOffsetOffset, SupportBuffer.FieldSize);
+ }
+ }
+
///
/// Sets the scale of all output render targets (they should all have the same scale).
///
diff --git a/src/Ryujinx.Graphics.Gpu/Window.cs b/src/Ryujinx.Graphics.Gpu/Window.cs
index 5c3463f2a..479b236ad 100644
--- a/src/Ryujinx.Graphics.Gpu/Window.cs
+++ b/src/Ryujinx.Graphics.Gpu/Window.cs
@@ -56,6 +56,13 @@ namespace Ryujinx.Graphics.Gpu
///
public object UserObj { get; }
+ ///
+ /// DLSS Mode B sub-pixel jitter offset this frame was rendered with, snapshotted at enqueue and
+ /// carried through the queue so the present can hand the matching offset to DLSS.
+ ///
+ public float JitterX { get; }
+ public float JitterY { get; }
+
///
/// Creates a new instance of the presentation texture.
///
@@ -73,7 +80,9 @@ namespace Ryujinx.Graphics.Gpu
ImageCrop crop,
Action acquireCallback,
Action