Skip to content

Instantly share code, notes, and snippets.

@emoose
Last active April 30, 2025 15:25
Show Gist options
  • Save emoose/11271bbb3b42fb3b1b0e1c83eef47c05 to your computer and use it in GitHub Desktop.
Save emoose/11271bbb3b42fb3b1b0e1c83eef47c05 to your computer and use it in GitHub Desktop.
PowerShell script/module that allows globally updating DLSS for all games
# Global DLSS update script by emoose - https://gist.github.com/emoose/11271bbb3b42fb3b1b0e1c83eef47c05
# Allows setting up driver to use a single global DLSS DLL for majority of DLSS2/3 games
# If the global version is newer than the one included with game, it should get loaded automatically
# (how this works: https://forums.guru3d.com/threads/.439761/page-143#post-6221767)
#
# Almost all DLSS3 games should work, DLSS2 is hit-and-miss
# (DLSS2 games with customized appid probably won't work, thanks to some pointless nvngx checks)
# DLSSD/DLSSG should work fine with nearly all games (re-run the script for each DLL you want to update)
#
# Usage:
# - press the Raw button on the right side, select all contents with CTRL+A, copy with CTRL+C (don't download as file as PS won't allow execution)
# - paste contents into notepad, save as UpdateDLSS.ps1
# - find the saved script, right click -> "Run with PowerShell"
# - when asked for DLL path, drag+drop an nvngx_dlss file into the window, and press enter
# - if Run with PowerShell option doesn't appear, you can also run through command prompt or powershell: "powershell C:\Users\emoose\Downloads\UpdateDLSS.ps1"
#
# To undo the changes from this script just clear out the "C:\ProgramData\NVIDIA\NGX\models" folder
# This folder should regen the next time DLSS is used, and games will go back to using the DLL from their game folder
#
# Advanced setup (installing as PowerShell module):
# - save script as UpdateDLSS.psm1 into powershell modules folder, so you can use it from any location
# Depending on PS version, save to either:
# - Documents\WindowsPowerShell\Modules\UpdateDLSS\UpdateDLSS.psm1
# - Documents\PowerShell\Modules\UpdateDLSS\UpdateDLSS.psm1
# Alternatively System32 should work for all PS versions:
# - C:\Windows\system32\WindowsPowerShell\v1.0\Modules\UpdateDLSS\UpdateDLSS.psm1
# With it saved into modules folder, you should be able to open a new powershell window and then run "UpdateDLSS" from any location
# (or run "UpdateDLSS -DllPath C:\DLLs\nvngx_dlss.dll")
#
# If ran without -DllPath param you'll be prompted for the path to the DLSS DLL
# When prompted you can usually just drag+drop the DLL into the powershell window
# Admin access shouldn't be required for this script
#
# Changelog:
# 2025-01-27: further snippet type improvements, renamed to UpdateDLSS.ps1 for easier usage
# 2025-01-26: improved snippet type detection, updated comments
# 2025-01-24: updated to get correct version of v310 files
function Update-IniFile {
param (
[string]$FilePath,
[string]$Section,
[string]$Key,
[string]$Value
)
$content = Get-Content $FilePath
$sectionExists = $false
$keyExists = $false
# Loop through each line in the content
for ($i = 0; $i -lt $content.Count; $i++) {
$line = $content[$i]
# Check if the line contains the section header
if ($line -match "^\[$Section\]") {
$sectionExists = $true
# Search for the key in subsequent lines within the same section
for ($j = $i + 1; $j -lt $content.Count; $j++) {
$line = $content[$j]
# Break out of loop if new section has started
if ($line.StartsWith("[") -And $line.EndsWith("]")) {
break
}
# Check if the line contains the key
if ($line -match "^$Key\s*=") {
# Update the value
$content[$j] = "$Key = $Value"
$keyExists = $true
break
}
}
# If the key doesn't exist, add it to the section
if (-not $keyExists) {
# Insert the key-value pair at the start of this section
$content[$i] = $content[$i] + "`r`n$Key = $Value"
}
break
}
}
# If the section doesn't exist, add it along with the key
if (-not $sectionExists) {
$content += "[$Section]`r`n"
$content += "$Key = $Value`r`n"
}
# Write the updated content back to the INI file
$content | Set-Content $FilePath
}
function UpdateDLSS {
param (
[Parameter(Mandatory=$true)]
[string]$DllPath
)
$nvngxDllPath = $DllPath.Trim(" ").Trim('"').Trim(" ")
$nvngxDllType = $null
$fileName = (Split-Path $nvngxDllPath -Leaf)
if ($fileName -notlike '*_*') {
Write-Host "Error: Invalid input DLL filename (no underscores?), aborting script."
return
}
$fileName = $fileName.Split('_')[1] -replace '\.dll$'
# User might have passed us a filename with extraneous chars, eg nvngx_dlss (1).dll
# Try extracting relevant part from it and check against known snippet names
# Extract the first 5 characters if the string is long enough, otherwise extract 4
$extractedValue = if ($fileName.Length -ge 5) { $fileName.Substring(0, 5) } else { $fileName.Substring(0, 4) }
# Check if the extracted value matches one of the desired values
if ($extractedValue -in 'dlss', 'dlssg', 'dlssd') {
$nvngxDllType = $extractedValue
} elseif ($fileName -in 'dlss', 'dlssg', 'dlssd') {
# Handle cases where the filename is exactly one of the desired values
$nvngxDllType = $fileName
}
# Check if $nvngxDllType is still null
if ($null -eq $nvngxDllType) {
# Last chance, check if it might be dlss
if ($fileName.Substring(0, 4) -eq "dlss") {
$nvngxDllType = "dlss"
} else {
Write-Host "Error: Unable to determine the DLL type from the filename. Please check the input: $nvngxDllPath"
Write-Host "Aborting script."
return
}
}
# DllImport needs full DLL path, try figuring it out:
$DllPath = [System.IO.Path]::GetFullPath($nvngxDllPath)
if (-not (Test-Path $DllPath)) {
$DllPath = Join-Path -Path $PWD -ChildPath $nvngxDllPath
if (-not (Test-Path $DllPath)) {
$DllPath = Join-Path -Path $PSScriptRoot -ChildPath $nvngxDllPath
if (-not (Test-Path $DllPath)) {
Write-Host "Error: Input DLL path not found: $nvngx_filename"
Write-Host "Aborting script."
return
}
}
}
Write-Host "Input DLL path: $DllPath"
$signature = Get-AuthenticodeSignature -FilePath $DllPath
if ($signature.Status -ne "Valid") {
Write-Host "Error: Input DLL doesn't have a valid authenticode signature."
Write-Host "UpdateDLSS requires loading/executing the DLL to work, which may be a risk."
Write-Host "Aborting script."
return
}
# DllImport code
$dllimport = @"
[DllImport(@"$DllPath", CallingConvention = CallingConvention.Cdecl)]
public static extern int NVSDK_NGX_GetSnippetVersion();
"@
# Generate random string to use for class name above, so script can be ran multiple times in same session
$length = 10
$randomString = -join ((65..90) + (97..122) | Get-Random -Count $length | ForEach-Object { [char]$_ })
$type = Add-Type -MemberDefinition $dllimport -Name "NGX$randomString" -Namespace "NV" -PassThru
$nvngxVersion = 0
try {
$nvngxVersion = $type::NVSDK_NGX_GetSnippetVersion()
} catch {
Write-Host "Error: Failed to execute NVSDK_NGX_GetSnippetVersion, error: $_"
return
}
$ver = [BitConverter]::GetBytes($nvngxVersion)
$verMajor = [BitConverter]::ToUInt16($ver, 2)
# Seems we don't need the result of NVSDK_NGX_GetGPUArchitecture, 160 always works fine?
#$nvngxDllArch = $type::NVSDK_NGX_GetGPUArchitecture().ToString('X')
$nvngxDllArch = "160"
$nvngxBasePath = "C:\ProgramData\NVIDIA\NGX\models"
$dllDestPath = "$nvngxBasePath\$nvngxDllType\versions\$nvngxVersion\files\$($nvngxDllArch)_E658703.bin"
$configFilePath = "$nvngxBasePath\nvngx_config.txt"
$configKey = "app_E658703"
$configValue = "$($verMajor).$($ver[1]).$($ver[0])"
Write-Host " "
Write-Host "Detected NVNGX DLL info:"
Write-Host " Type: $nvngxDllType"
Write-Host " Version: $configValue"
Write-Host " Signature: $($signature.Status)"
Write-Host " "
Write-Host "The following operations will be performed:"
Write-Host "1. Copy DLL to $dllDestPath"
Write-Host "2. Update config file $configFilePath with the following:"
Write-Host " [$nvngxDllType]"
Write-Host " $configKey = $configValue"
Write-Host " "
if (Test-Path $dllDestPath) {
Write-Host "Error: DLL destination already exists, script aborted."
return
}
$confirmation = Read-Host "Do you want to proceed? (y/n)"
if ($confirmation.ToLower() -ne 'y') {
Write-Host "Operation canceled by user."
return
}
# Create folders if needed
if (-not (Test-Path (Split-Path $dllDestPath))) {
New-Item -ItemType Directory -Force -Path (Split-Path $dllDestPath) | Out-Null
}
# Copy DLL
Copy-Item -Path $DllPath -Destination $dllDestPath -Force
if (-not (Test-Path $configFilePath)) {
Write-Host "Config file doesn't exist, creating $configFilePath"
New-Item -Path $configFilePath -ItemType File > $null
}
# Update config file
Update-IniFile -FilePath $configFilePath -Section $nvngxDllType -Key $configKey -Value $configValue
Write-Host "Operations completed successfully."
}
try
{
Export-ModuleMember -Function "UpdateDLSS"
} catch {
UpdateDLSS
}
@rajkosto
Copy link

rajkosto commented Feb 8, 2025

hello, i used that script but sometimes the nvidia app crash or it stay loading in loop someone know how to fix?

it does this ocasionally if ApplicationStorage.json is made read-only.

@DeathWrench
Copy link

hello, i used that script but sometimes the nvidia app crash or it stay loading in loop someone know how to fix?

you can try this one:
https://gist.github.com/rajkosto/6bb60346d8a7f7f4e21566618e44020a
or just uninstall nvidia app

@NextWork123
Copy link

hello, i used that script but sometimes the nvidia app crash or it stay loading in loop someone know how to fix?

you can try this one: https://gist.github.com/rajkosto/6bb60346d8a7f7f4e21566618e44020a or just uninstall nvidia app

yeah seem to work that

@rajkosto
Copy link

rajkosto commented Feb 8, 2025

I've updated my code to also search/replace the override disables in the ApplicationOntology fingerprint.db which is the source of the starting values that the json file gets populated with when a new game gets detected, and then it sets the fingerprint.db to READ ONLY (setting the actual ApplicationStorage.json to READ ONLY causes NVContainer to crash occasionally so it's not a viable option)

So make sure to RE-DOWNLOAD AND RE-RUN THE SearchReplaceNvidiaApp.exe if you already have it.

@NextWork123
Copy link

I've updated my code to also search/replace the override disables in the ApplicationOntology fingerprint.db which is the source of the starting values that the json file gets populated with when a new game gets detected, and then it sets the fingerprint.db to READ ONLY (setting the actual ApplicationStorage.json to READ ONLY causes NVContainer to crash occasionally so it's not a viable option)

So make sure to RE-DOWNLOAD AND RE-RUN THE SearchReplaceNvidiaApp.exe if you already have it.

is possible to add new games for be on nvidia app? like soulframe?

@rajkosto
Copy link

rajkosto commented Feb 9, 2025

if the game isn't available in nvidia app then you don't have to worry about it messing with your profiles that you edit with nvidiaProfileInspector, either the global one or making a new game specific one and overriding DLSS there like this: https://images.sshnuke.net/2025-02-06_08-52-29_LWV7nXacu.png

@BitGrub
Copy link

BitGrub commented Feb 21, 2025

Having trouble forcing preset K globally using inspector. Can someone help me out step by step? I've run the script and the latest dll IS loaded as expected

@wandaww
Copy link

wandaww commented Feb 21, 2025

uhm hai, i still get preset E on black ops 6 but someone in reddit got a preset K after using this step. so i wonder how to get preset K on black ops 6 while my game is already on dlss 310.2.1 using this script
{32BDDE00-FB8F-4BBA-BBB1-635DF5BA3939}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment