aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/vulkan_common/streamline.h
diff options
context:
space:
mode:
authorDuck912 <350528965+Duck912@users.noreply.github.com>2026-11-03 12:13:35 -0500
committerDuck912 <350528965+Duck912@users.noreply.github.com>2026-11-03 12:33:16 -0500
commit63e87a22c60394bc4f427ee5f8d6ddbce7b0ac7f (patch)
tree959ffe32400de4cd727c0c5655e391591d6485a6 /src/video_core/vulkan_common/streamline.h
parent1d4ccdbb0cf01add647247a4ab64b5060b1bb8eb (diff)
video_core: NVIDIA DLSS through NVIDIA Streamline in place of a game's DLSS
Adds a Graphics setting, "Use NVIDIA DLSS in place of a game's DLSS" (nvidia_dlss, off by default). When it is on, in Windows builds configured with EGLANTINE_STREAMLINE_SDK, the evaluation Eglantine already replaces with FSR 3.1 goes to NVIDIA DLSS on GeForce RTX cards, with the same inputs (colour, depth, motion vectors, jitter). When DLSS can't run, FSR 3.1 runs as before. Only Streamline's MIT-licensed headers are compiled in; nothing of NVIDIA's is linked or shipped. At run time Eglantine looks for sl.interposer.dll in the user folder's "streamline" folder (or EDEN_STREAMLINE_DIR, or "streamline" next to the executable), checks its Streamline signature and starts Streamline with manual hooking. Streamline's plugins come from that folder or the NVIDIA app's downloads. DLSS itself is nvngx_dlss.dll in the same folder, else the newest DLSS 310 or later that the NVIDIA app has downloaded, checked for NVIDIA's Authenticode signature and copied as streamline/nvidia-app/nvngx_dlss.dll. Like other tools that call DLSS outside a game, it uses its own fixed project id with the custom engine type. - Preset K for all modes (EDEN_NX2_DLSS_PRESET overrides it): the default Performance model (M) and L draw thin dark horizontal lines in some frames at 2x resolution scale; K doesn't. - HDR input with auto exposure; the mode follows the render/output ratio. - Buffer device address stays enabled when DLSS needs it, for DLSS only. - The upscaler waits for the device instead of submitting when it is destroyed: by then the game's channels are released, and a submit read the state tracker's stale flags (a crash when stopping a game). With the setting off, or in builds without the SDK path (the setting is hidden there), nothing changes. Testing: Windows 11, RTX 5080, Fire Emblem: Fortune's Weave docked at 1x (720p -> 1440p) and 2x (1440p -> 2880p), CLI runs and GUI play, stopping and restarting games with DLSS on. Not tested on other GPUs or games. Assisted-by: Claude Opus 5.5 (implementation, debugging) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
Diffstat (limited to 'src/video_core/vulkan_common/streamline.h')
-rw-r--r--src/video_core/vulkan_common/streamline.h63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/video_core/vulkan_common/streamline.h b/src/video_core/vulkan_common/streamline.h
new file mode 100644
index 0000000000..47e55f7150
--- /dev/null
+++ b/src/video_core/vulkan_common/streamline.h
@@ -0,0 +1,63 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+// NVIDIA DLSS through NVIDIA Streamline. Only Streamline's MIT-licensed
+// headers are built in: NVIDIA's DLLs are loaded at run time from the user's PC, and none ship
+// with the emulator.
+
+#pragma once
+
+#include <filesystem>
+#include <string>
+#include <vector>
+
+#include "common/common_types.h"
+#include "video_core/vulkan_common/vulkan_wrapper.h"
+
+namespace Vulkan::Streamline {
+
+/// NVIDIA's files DLSS needs, as found on this PC. Paths are empty when missing.
+struct DlssFiles {
+ std::filesystem::path folder; ///< Where the loader is, or where it should go
+ std::filesystem::path interposer; ///< sl.interposer.dll (Streamline's loader)
+ std::filesystem::path model; ///< nvngx_dlss.dll next to the loader
+ std::filesystem::path app_model; ///< Newest DLSS the NVIDIA app downloaded
+ std::string interposer_version;
+ std::string model_version;
+ std::string app_model_version;
+};
+
+[[nodiscard]] DlssFiles FindDlssFiles();
+
+/// The user folder's "streamline" folder.
+[[nodiscard]] std::filesystem::path UserFolder();
+
+/// Streamline's own modules carry a second, Streamline-only signature.
+[[nodiscard]] bool IsStreamlineModule(const std::filesystem::path& path);
+
+/// A valid Authenticode signature from NVIDIA Corporation (DLSS models).
+[[nodiscard]] bool IsSignedByNvidia(const std::filesystem::path& path);
+
+/// When the NVIDIA DLSS setting is on, loads the user's sl.interposer.dll (checking NVIDIA's
+/// signature) and starts Streamline for DLSS. Call before creating the renderer's instance.
+bool Start();
+
+/// Whether Streamline is running and waiting for the renderer's device.
+[[nodiscard]] bool WantsDevice();
+
+/// Instance and device extensions DLSS asks for (empty when Streamline isn't running).
+[[nodiscard]] std::vector<std::string> InstanceExtensions();
+[[nodiscard]] std::vector<std::string> DeviceExtensions();
+
+/// Hands the renderer's device to Streamline and routes the swapchain calls through it, as
+/// Streamline's manual hooking needs. Stops Streamline and returns false when DLSS can't run.
+bool AttachDevice(VkInstance instance, VkPhysicalDevice physical, VkDevice device,
+ u32 graphics_family, vk::DeviceDispatch& dld);
+
+/// Whether DLSS can run on the attached device.
+[[nodiscard]] bool IsDlssAvailable();
+
+/// Shuts Streamline down; call before the device is destroyed.
+void Stop();
+
+} // namespace Vulkan::Streamline