├── .gitattributes ├── .github └── workflows │ └── build.yml ├── .gitignore ├── .gitmodules ├── CyberFSR.sln ├── CyberFSR ├── Config.cpp ├── Config.h ├── CyberFSR.rc ├── CyberFSR.vcxproj ├── CyberFSR.vcxproj.filters ├── CyberFsr.cpp ├── CyberFsr.h ├── CyberFsrDx11.cpp ├── CyberFsrDx12.cpp ├── CyberFsrVk.cpp ├── DebugOverlay.cpp ├── DebugOverlay.h ├── DirectXHooks.cpp ├── DirectXHooks.h ├── NvParameter.cpp ├── NvParameter.h ├── Util.cpp ├── Util.h ├── ViewMatrixHook.cpp ├── ViewMatrixHook.h ├── dllmain.cpp ├── framework.h ├── pch.cpp ├── pch.h ├── resource.h ├── scanner.cpp └── scanner.h ├── LICENSE ├── README.md ├── linuxinstall.sh └── nvngx.ini /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: MSBuild 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | env: 10 | SOLUTION_FILE_PATH: CyberFSR.sln 11 | BUILD_CONFIGURATION: Release 12 | 13 | permissions: 14 | contents: read 15 | 16 | jobs: 17 | build: 18 | runs-on: windows-latest 19 | 20 | steps: 21 | - uses: actions/checkout@v3 22 | with: 23 | submodules: recursive 24 | 25 | - name: Add MSBuild to PATH 26 | uses: microsoft/setup-msbuild@v1.1.3 27 | with: 28 | msbuild-architecture: x64 29 | 30 | - name: Prepare Vulkan SDK 31 | uses: humbletim/setup-vulkan-sdk@v1.2.0 32 | with: 33 | vulkan-query-version: latest 34 | vulkan-components: Vulkan-Headers, Vulkan-Loader 35 | vulkan-use-cache: true 36 | 37 | - name: Generate FSR 2.0 Solution 38 | working-directory: ${{ github.workspace }}\external\FidelityFX-FSR2\build 39 | run: .\GenerateSolutions.bat 40 | 41 | - name: Build FSR 2.0 for DirectX 12 42 | working-directory: ${{ github.workspace }}\external\FidelityFX-FSR2\build\DX12 43 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} FSR2_Sample_DX12.sln 44 | 45 | - name: Build FSR 2.0 for Vulkan 46 | working-directory: ${{ github.workspace }}\external\FidelityFX-FSR2\build\VK 47 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} FSR2_Sample_VK.sln 48 | 49 | - name: Build 50 | working-directory: ${{ github.workspace }} 51 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}} 52 | 53 | - uses: actions/upload-artifact@v2 54 | with: 55 | name: CyberFSR2 56 | path: ${{ github.workspace }}\x64\Release 57 | if-no-files-found: error 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 298 | *.vbp 299 | 300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 301 | *.dsw 302 | *.dsp 303 | 304 | # Visual Studio 6 technical files 305 | *.ncb 306 | *.aps 307 | 308 | # Visual Studio LightSwitch build output 309 | **/*.HTMLClient/GeneratedArtifacts 310 | **/*.DesktopClient/GeneratedArtifacts 311 | **/*.DesktopClient/ModelManifest.xml 312 | **/*.Server/GeneratedArtifacts 313 | **/*.Server/ModelManifest.xml 314 | _Pvt_Extensions 315 | 316 | # Paket dependency manager 317 | .paket/paket.exe 318 | paket-files/ 319 | 320 | # FAKE - F# Make 321 | .fake/ 322 | 323 | # CodeRush personal settings 324 | .cr/personal 325 | 326 | # Python Tools for Visual Studio (PTVS) 327 | __pycache__/ 328 | *.pyc 329 | 330 | # Cake - Uncomment if you are using it 331 | # tools/** 332 | # !tools/packages.config 333 | 334 | # Tabs Studio 335 | *.tss 336 | 337 | # Telerik's JustMock configuration file 338 | *.jmconfig 339 | 340 | # BizTalk build output 341 | *.btp.cs 342 | *.btm.cs 343 | *.odx.cs 344 | *.xsd.cs 345 | 346 | # OpenCover UI analysis results 347 | OpenCover/ 348 | 349 | # Azure Stream Analytics local run output 350 | ASALocalRun/ 351 | 352 | # MSBuild Binary and Structured Log 353 | *.binlog 354 | 355 | # NVidia Nsight GPU debugger configuration file 356 | *.nvuser 357 | 358 | # MFractors (Xamarin productivity tool) working folder 359 | .mfractor/ 360 | 361 | # Local History for Visual Studio 362 | .localhistory/ 363 | 364 | # Visual Studio History (VSHistory) files 365 | .vshistory/ 366 | 367 | # BeatPulse healthcheck temp database 368 | healthchecksdb 369 | 370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 371 | MigrationBackup/ 372 | 373 | # Ionide (cross platform F# VS Code tools) working folder 374 | .ionide/ 375 | 376 | # Fody - auto-generated XML schema 377 | FodyWeavers.xsd 378 | 379 | # VS Code files for those working on multiple tools 380 | .vscode/* 381 | !.vscode/settings.json 382 | !.vscode/tasks.json 383 | !.vscode/launch.json 384 | !.vscode/extensions.json 385 | *.code-workspace 386 | 387 | # Local History for Visual Studio Code 388 | .history/ 389 | 390 | # Windows Installer files from build outputs 391 | *.cab 392 | *.msi 393 | *.msix 394 | *.msm 395 | *.msp 396 | 397 | # JetBrains Rider 398 | *.sln.iml 399 | 400 | # Prerequisites 401 | *.d 402 | 403 | # Compiled Object files 404 | *.slo 405 | *.lo 406 | *.o 407 | *.obj 408 | 409 | # Precompiled Headers 410 | *.gch 411 | *.pch 412 | 413 | # Compiled Dynamic libraries 414 | *.so 415 | *.dylib 416 | *.dll 417 | 418 | # Fortran module files 419 | *.mod 420 | *.smod 421 | 422 | # Compiled Static libraries 423 | *.lai 424 | *.la 425 | *.a 426 | *.lib 427 | 428 | # Executables 429 | *.exe 430 | *.out 431 | *.app 432 | CyberFSR/imgui.ini 433 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/nvngx_dlss_sdk"] 2 | path = external/nvngx_dlss_sdk 3 | url = https://github.com/PotatoOfDoom/DLSS.git 4 | [submodule "external/FidelityFX-FSR2"] 5 | path = external/FidelityFX-FSR2 6 | url = https://github.com/PotatoOfDoom/FidelityFX-FSR2 7 | [submodule "external/simpleini"] 8 | path = external/simpleini 9 | url = https://github.com/brofield/simpleini 10 | [submodule "external/unordered_dense"] 11 | path = external/unordered_dense 12 | url = https://github.com/martinus/unordered_dense.git -------------------------------------------------------------------------------- /CyberFSR.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32602.215 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CyberFSR", "CyberFSR\CyberFSR.vcxproj", "{8D2B73FB-EECD-45CE-B8E5-335610462F58}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {8D2B73FB-EECD-45CE-B8E5-335610462F58}.Debug|x64.ActiveCfg = Debug|x64 17 | {8D2B73FB-EECD-45CE-B8E5-335610462F58}.Debug|x64.Build.0 = Debug|x64 18 | {8D2B73FB-EECD-45CE-B8E5-335610462F58}.Debug|x86.ActiveCfg = Debug|Win32 19 | {8D2B73FB-EECD-45CE-B8E5-335610462F58}.Debug|x86.Build.0 = Debug|Win32 20 | {8D2B73FB-EECD-45CE-B8E5-335610462F58}.Release|x64.ActiveCfg = Release|x64 21 | {8D2B73FB-EECD-45CE-B8E5-335610462F58}.Release|x64.Build.0 = Release|x64 22 | {8D2B73FB-EECD-45CE-B8E5-335610462F58}.Release|x86.ActiveCfg = Release|Win32 23 | {8D2B73FB-EECD-45CE-B8E5-335610462F58}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {56931951-7F8D-4575-BED5-EE54F24DE751} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /CyberFSR/Config.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Config.h" 3 | #include "Util.h" 4 | 5 | Config::Config(std::wstring fileName) 6 | { 7 | absoluteFileName = Util::DllPath().parent_path() / fileName; 8 | 9 | Reload(); 10 | } 11 | 12 | void Config::Reload() 13 | { 14 | if (ini.LoadFile(absoluteFileName.c_str()) == SI_OK) 15 | { 16 | // Depth 17 | DepthInverted = readBool("Depth", "DepthInverted"); 18 | 19 | // Color 20 | AutoExposure = readBool("Color", "AutoExposure"); 21 | HDR = readBool("Color", "HDR"); 22 | 23 | // MotionVectors 24 | JitterCancellation = readBool("MotionVectors", "JitterCancellation"); 25 | DisplayResolution = readBool("MotionVectors", "DisplayResolution"); 26 | 27 | // Sharpening 28 | EnableSharpening = readBool("Sharpening", "EnableSharpening"); 29 | Sharpness = readFloat("Sharpening", "Sharpness"); 30 | SharpnessRange = readSharpnessRange("Sharpening", "SharpnessRange"); 31 | 32 | //Upscale Ratio Override 33 | UpscaleRatioOverrideEnabled = readBool("UpscaleRatio", "UpscaleRatioOverrideEnabled"); 34 | UpscaleRatioOverrideValue = readFloat("UpscaleRatio", "UpscaleRatioOverrideValue"); 35 | 36 | // Quality Overrides 37 | QualityRatioOverrideEnabled = readBool("QualityOverrides", "QualityRatioOverrideEnabled"); 38 | if (QualityRatioOverrideEnabled) { 39 | QualityRatio_UltraQuality = readFloat("QualityOverrides", "QualityRatioUltraQuality"); 40 | QualityRatio_Quality = readFloat("QualityOverrides", "QualityRatioQuality"); 41 | QualityRatio_Balanced = readFloat("QualityOverrides", "QualityRatioBalanced"); 42 | QualityRatio_Performance = readFloat("QualityOverrides", "QualityRatioPerformance"); 43 | QualityRatio_UltraPerformance = readFloat("QualityOverrides", "QualityRatioUltraPerformance"); 44 | } 45 | 46 | 47 | // View 48 | Method = readViewMethod("View", "Method"); 49 | VerticalFOV = readFloat("View", "VerticalFOV"); 50 | NearPlane = readFloat("View", "NearPlane"); 51 | FarPlane = readFloat("View", "FarPlane"); 52 | InfiniteFarPlane = readBool("View", "InfiniteFarPlane"); 53 | 54 | DisableReactiveMask = readBool("Hotfix", "DisableReactiveMask"); 55 | } 56 | 57 | auto exeName = Util::ExePath().filename(); 58 | 59 | if (exeName == L"Cyberpunk2077.exe") 60 | { 61 | Method = Method.value_or(ViewMethod::Cyberpunk2077); 62 | } 63 | else if (exeName == L"DyingLightGame_x64_rwdi.exe") 64 | { 65 | Method = Method.value_or(ViewMethod::DL2); 66 | } 67 | else if (exeName == L"RDR2.exe") 68 | { 69 | Method = Method.value_or(ViewMethod::RDR2); 70 | } 71 | } 72 | 73 | std::optional Config::readString(std::string section, std::string key, bool lowercase) 74 | { 75 | std::string value = ini.GetValue(section.c_str(), key.c_str(), "auto"); 76 | 77 | std::string lower = value; 78 | std::transform( 79 | lower.begin(), lower.end(), 80 | lower.begin(), 81 | [](unsigned char c) 82 | { 83 | return std::tolower(c); 84 | } 85 | ); 86 | 87 | if (lower == "auto") 88 | { 89 | return std::nullopt; 90 | } 91 | return lowercase ? lower : value; 92 | } 93 | 94 | std::optional Config::readFloat(std::string section, std::string key) 95 | { 96 | auto value = readString(section, key); 97 | try 98 | { 99 | return std::stof(value.value()); 100 | } 101 | catch (const std::bad_optional_access&) // missing or auto value 102 | { 103 | return std::nullopt; 104 | } 105 | catch (const std::invalid_argument&) // invalid float string for std::stof 106 | { 107 | return std::nullopt; 108 | } 109 | catch (const std::out_of_range&) // out of range for 32 bit float 110 | { 111 | return std::nullopt; 112 | } 113 | } 114 | 115 | std::optional Config::readBool(std::string section, std::string key) 116 | { 117 | auto value = readString(section, key, true); 118 | if (value == "true") 119 | { 120 | return true; 121 | } 122 | else if (value == "false") 123 | { 124 | return false; 125 | } 126 | 127 | return std::nullopt; 128 | } 129 | 130 | std::optional Config::readSharpnessRange(std::string section, std::string key) 131 | { 132 | auto value = readString(section, key, true); 133 | if (value == "normal") 134 | { 135 | return SharpnessRangeModifier::Normal; 136 | } 137 | else if (value == "extended") 138 | { 139 | return SharpnessRangeModifier::Extended; 140 | } 141 | 142 | return std::nullopt; 143 | } 144 | 145 | std::optional Config::readViewMethod(std::string section, std::string key) 146 | { 147 | auto value = readString(section, key, true); 148 | if (value == "config") 149 | { 150 | return ViewMethod::Config; 151 | } 152 | else if (value == "cyberpunk2077") 153 | { 154 | return ViewMethod::Cyberpunk2077; 155 | } 156 | else if (value == "rdr2") 157 | { 158 | return ViewMethod::RDR2; 159 | } 160 | else if (value == "dl2") 161 | { 162 | return ViewMethod::DL2; 163 | } 164 | 165 | return std::nullopt; 166 | } 167 | -------------------------------------------------------------------------------- /CyberFSR/Config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pch.h" 3 | 4 | enum class SharpnessRangeModifier 5 | { 6 | Normal, 7 | Extended, 8 | }; 9 | 10 | enum class ViewMethod 11 | { 12 | Config, 13 | Cyberpunk2077, 14 | RDR2, 15 | DL2, 16 | }; 17 | 18 | class Config 19 | { 20 | public: 21 | Config(std::wstring fileName); 22 | 23 | // Depth 24 | std::optional DepthInverted; 25 | 26 | // Color 27 | std::optional AutoExposure; 28 | std::optional HDR; 29 | 30 | // Motion 31 | std::optional JitterCancellation; 32 | std::optional DisplayResolution; 33 | 34 | // Sharpening 35 | std::optional EnableSharpening; 36 | std::optional Sharpness; 37 | std::optional SharpnessRange; 38 | 39 | // Upscale Ratio Override 40 | std::optional UpscaleRatioOverrideEnabled; 41 | std::optional UpscaleRatioOverrideValue; 42 | 43 | // Quality Overrides 44 | std::optional QualityRatioOverrideEnabled; 45 | std::optional QualityRatio_UltraQuality; 46 | std::optional QualityRatio_Quality; 47 | std::optional QualityRatio_Balanced; 48 | std::optional QualityRatio_Performance; 49 | std::optional QualityRatio_UltraPerformance; 50 | 51 | // View 52 | std::optional Method; 53 | std::optional VerticalFOV; 54 | std::optional NearPlane; 55 | std::optional FarPlane; 56 | std::optional InfiniteFarPlane; 57 | 58 | //Hotfix for Steam Deck 59 | std::optional DisableReactiveMask; 60 | 61 | void Reload(); 62 | 63 | private: 64 | CSimpleIniA ini; 65 | 66 | std::filesystem::path absoluteFileName; 67 | 68 | std::optional readString(std::string section, std::string key, bool lowercase = false); 69 | std::optional readFloat(std::string section, std::string key); 70 | std::optional readBool(std::string section, std::string key); 71 | std::optional readSharpnessRange(std::string section, std::string key); 72 | std::optional readViewMethod(std::string section, std::string key); 73 | }; 74 | -------------------------------------------------------------------------------- /CyberFSR/CyberFSR.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "winres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (United Kingdom) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) 19 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK 20 | #pragma code_page(1252) 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Version 51 | // 52 | 53 | VS_VERSION_INFO VERSIONINFO 54 | FILEVERSION 2,0,0,1 55 | PRODUCTVERSION 2,0,0,1 56 | FILEFLAGSMASK 0x3fL 57 | #ifdef _DEBUG 58 | FILEFLAGS 0x1L 59 | #else 60 | FILEFLAGS 0x0L 61 | #endif 62 | FILEOS 0x40004L 63 | FILETYPE 0x2L 64 | FILESUBTYPE 0x0L 65 | BEGIN 66 | BLOCK "StringFileInfo" 67 | BEGIN 68 | BLOCK "080904b0" 69 | BEGIN 70 | VALUE "CompanyName", "CyberFSR" 71 | VALUE "FileDescription", "Unofficial CyberFSR 2.1.2 by MOVZX" 72 | VALUE "FileVersion", "2.0.0.1" 73 | VALUE "InternalName", "DLSS2FSR.dll" 74 | VALUE "LegalCopyright", "Copyright (C) 2022 PotatoOfDoom" 75 | VALUE "OriginalFilename", "DLSS2FSR.dll" 76 | VALUE "ProductName", "DLSS2FSR" 77 | VALUE "ProductVersion", "2.0.0.1" 78 | END 79 | END 80 | BLOCK "VarFileInfo" 81 | BEGIN 82 | VALUE "Translation", 0x809, 1200 83 | END 84 | END 85 | 86 | #endif // English (United Kingdom) resources 87 | ///////////////////////////////////////////////////////////////////////////// 88 | 89 | 90 | 91 | #ifndef APSTUDIO_INVOKED 92 | ///////////////////////////////////////////////////////////////////////////// 93 | // 94 | // Generated from the TEXTINCLUDE 3 resource. 95 | // 96 | 97 | 98 | ///////////////////////////////////////////////////////////////////////////// 99 | #endif // not APSTUDIO_INVOKED 100 | 101 | -------------------------------------------------------------------------------- /CyberFSR/CyberFSR.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {8d2b73fb-eecd-45ce-b8e5-335610462f58} 25 | CyberFSR 26 | 10.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v143 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v143 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v143 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v143 52 | true 53 | Unicode 54 | x64 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | $(SolutionDir)external\simpleini;$(SolutionDir)external\nvngx_dlss_sdk\include;$(SolutionDir)external\FidelityFX-FSR2\src;$(VULKAN_SDK)\Include;$(IncludePath) 76 | 77 | 78 | $(SolutionDir)external\simpleini;$(SolutionDir)external\nvngx_dlss_sdk\include;$(SolutionDir)external\FidelityFX-FSR2\src;$(VULKAN_SDK)\Include;$(IncludePath) 79 | 80 | 81 | $(SolutionDir)external\simpleini;$(SolutionDir)external\nvngx_dlss_sdk\include;$(SolutionDir)external\FidelityFX-FSR2\src;$(VULKAN_SDK)\Include;$(IncludePath) 82 | $(SolutionDir)external\FidelityFX-FSR2\bin\ffx_fsr2_api;$(VULKAN_SDK)\Lib;$(LibraryPath) 83 | 84 | 85 | $(SolutionDir)external\simpleini;$(SolutionDir)external\nvngx_dlss_sdk\include;$(SolutionDir)external\FidelityFX-FSR2\src;$(VULKAN_SDK)\Include;$(IncludePath) 86 | nvngx 87 | $(SolutionDir)external\FidelityFX-FSR2\bin\ffx_fsr2_api;$(VULKAN_SDK)\Lib;$(LibraryPath) 88 | 89 | 90 | 91 | Level3 92 | true 93 | WIN32;_DEBUG;CYBERFSR_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 94 | true 95 | Use 96 | pch.h 97 | stdcpplatest 98 | 99 | 100 | Windows 101 | true 102 | false 103 | 104 | 105 | 106 | 107 | Level3 108 | true 109 | true 110 | true 111 | WIN32;NDEBUG;CYBERFSR_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 112 | true 113 | Use 114 | pch.h 115 | stdcpplatest 116 | 117 | 118 | Windows 119 | true 120 | true 121 | true 122 | false 123 | 124 | 125 | 126 | 127 | Level3 128 | true 129 | _DEBUG;CYBERFSR_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 130 | true 131 | Use 132 | pch.h 133 | stdcpplatest 134 | true 135 | 136 | 137 | Windows 138 | true 139 | false 140 | vulkan-1.lib;ffx_fsr2_api_x64d.lib;ffx_fsr2_api_dx12_x64d.lib;ffx_fsr2_api_vk_x64d.lib;%(AdditionalDependencies) 141 | 142 | 143 | 144 | 145 | Level3 146 | true 147 | true 148 | NDEBUG;CYBERFSR_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 149 | true 150 | Use 151 | pch.h 152 | stdcpplatest 153 | Precise 154 | AnySuitable 155 | Speed 156 | true 157 | 158 | 159 | Windows 160 | true 161 | true 162 | true 163 | false 164 | vulkan-1.lib;ffx_fsr2_api_x64.lib;ffx_fsr2_api_dx12_x64.lib;ffx_fsr2_api_vk_x64.lib;%(AdditionalDependencies) 165 | UseLinkTimeCodeGeneration 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | Create 193 | Create 194 | Create 195 | Create 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 0x0809 204 | 205 | 206 | 207 | 208 | 209 | 210 | -------------------------------------------------------------------------------- /CyberFSR/CyberFSR.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 6 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 7 | 8 | 9 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 10 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | Source Files 64 | 65 | 66 | Source Files 67 | 68 | 69 | Source Files 70 | 71 | 72 | Source Files 73 | 74 | 75 | Source Files 76 | 77 | 78 | Source Files 79 | 80 | 81 | Source Files 82 | 83 | 84 | Source Files 85 | 86 | 87 | Source Files 88 | 89 | 90 | 91 | 92 | Resource Files 93 | 94 | 95 | Source Files 96 | 97 | 98 | Source Files 99 | 100 | 101 | -------------------------------------------------------------------------------- /CyberFSR/CyberFsr.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Config.h" 3 | #include "CyberFsr.h" 4 | #include "DirectXHooks.h" 5 | #include "Util.h" 6 | 7 | FeatureContext* CyberFsrContext::CreateContext() 8 | { 9 | auto handleId = rand(); 10 | Contexts[handleId] = std::make_unique(); 11 | Contexts[handleId]->Handle.Id = handleId; 12 | return Contexts[handleId].get(); 13 | } 14 | 15 | void CyberFsrContext::DeleteContext(NVSDK_NGX_Handle* handle) 16 | { 17 | auto handleId = handle->Id; 18 | 19 | auto it = std::find_if(Contexts.begin(), Contexts.end(), 20 | [&handleId](const auto& p) { return p.first == handleId; }); 21 | Contexts.erase(it); 22 | } 23 | 24 | CyberFsrContext::CyberFsrContext() 25 | { 26 | MyConfig = std::make_unique(L"nvngx.ini"); 27 | } 28 | -------------------------------------------------------------------------------- /CyberFSR/CyberFsr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pch.h" 3 | #include "ViewMatrixHook.h" 4 | #include "NvParameter.h" 5 | #include "DebugOverlay.h" 6 | 7 | class FeatureContext; 8 | 9 | //Global Context 10 | class CyberFsrContext 11 | { 12 | CyberFsrContext(); 13 | public: 14 | std::shared_ptr MyConfig; 15 | 16 | VkDevice VulkanDevice; 17 | VkInstance VulkanInstance; 18 | VkPhysicalDevice VulkanPhysicalDevice; 19 | 20 | std::shared_ptr NvParameterInstance = NvParameter::instance(); 21 | 22 | ankerl::unordered_dense::map > Contexts; 23 | FeatureContext* CreateContext(); 24 | void DeleteContext(NVSDK_NGX_Handle* handle); 25 | 26 | static std::shared_ptr instance() 27 | { 28 | static std::shared_ptr INSTANCE{new CyberFsrContext()}; 29 | return INSTANCE; 30 | } 31 | }; 32 | 33 | class FeatureContext 34 | { 35 | public: 36 | std::unique_ptr ViewMatrix; 37 | NVSDK_NGX_Handle Handle; 38 | ID3D12Device* DxDevice; 39 | FfxFsr2Context FsrContext; 40 | FfxFsr2ContextDescription FsrContextDescription; 41 | std::unique_ptr DebugLayer; 42 | std::vector ScratchBuffer; 43 | 44 | unsigned int Width{}, Height{}, RenderWidth{}, RenderHeight{}; 45 | NVSDK_NGX_PerfQuality_Value PerfQualityValue = NVSDK_NGX_PerfQuality_Value_Balanced; 46 | float Sharpness = 1.0f; 47 | float MVScaleX{}, MVScaleY{}; 48 | float JitterOffsetX{}, JitterOffsetY{}; 49 | }; 50 | -------------------------------------------------------------------------------- /CyberFSR/CyberFsrDx11.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "CyberFsr.h" 3 | 4 | NVSDK_NGX_Result NVSDK_NGX_D3D11_Init(void) 5 | { 6 | return NVSDK_NGX_Result_Success; 7 | } 8 | 9 | NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Shutdown(void) 10 | { 11 | return NVSDK_NGX_Result_Success; 12 | } 13 | 14 | NVSDK_NGX_Result NVSDK_NGX_D3D11_GetParameters(NVSDK_NGX_Parameter** OutParameters) 15 | { 16 | *OutParameters = CyberFsrContext::instance()->NvParameterInstance->AllocateParameters(); 17 | return NVSDK_NGX_Result_Success; 18 | } -------------------------------------------------------------------------------- /CyberFSR/CyberFsrDx12.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Config.h" 3 | #include "CyberFsr.h" 4 | #include "DirectXHooks.h" 5 | #include "Util.h" 6 | 7 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_Ext(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, 8 | ID3D12Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion, 9 | unsigned long long unknown0) 10 | { 11 | return NVSDK_NGX_Result_Success; 12 | } 13 | 14 | NVSDK_NGX_Result NVSDK_NGX_D3D12_Init(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, ID3D12Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) 15 | { 16 | return NVSDK_NGX_D3D12_Init_Ext(InApplicationId, InApplicationDataPath, InDevice, InFeatureInfo, InSDKVersion, 0); 17 | } 18 | 19 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_ProjectID(const char* InProjectId, NVSDK_NGX_EngineType InEngineType, const char* InEngineVersion, const wchar_t* InApplicationDataPath, ID3D12Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) 20 | { 21 | return NVSDK_NGX_D3D12_Init_Ext(0x1337, InApplicationDataPath, InDevice, InFeatureInfo, InSDKVersion, 0); 22 | } 23 | 24 | NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_with_ProjectID(const char* InProjectId, NVSDK_NGX_EngineType InEngineType, const char* InEngineVersion, const wchar_t* InApplicationDataPath, ID3D12Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) 25 | { 26 | return NVSDK_NGX_D3D12_Init_Ext(0x1337, InApplicationDataPath, InDevice, InFeatureInfo, InSDKVersion, 0); 27 | } 28 | 29 | NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Shutdown(void) 30 | { 31 | CyberFsrContext::instance()->NvParameterInstance->Params.clear(); 32 | CyberFsrContext::instance()->Contexts.clear(); 33 | return NVSDK_NGX_Result_Success; 34 | } 35 | 36 | NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Shutdown1(ID3D12Device* InDevice) 37 | { 38 | CyberFsrContext::instance()->NvParameterInstance->Params.clear(); 39 | CyberFsrContext::instance()->Contexts.clear(); 40 | return NVSDK_NGX_Result_Success; 41 | } 42 | 43 | //currently it's kind of hack but better than what it was previously -- External Memory Tracking 44 | NVSDK_NGX_Result NVSDK_NGX_D3D12_GetParameters(NVSDK_NGX_Parameter** OutParameters) 45 | { 46 | *OutParameters = CyberFsrContext::instance()->NvParameterInstance->AllocateParameters(); 47 | return NVSDK_NGX_Result_Success; 48 | } 49 | 50 | //currently it's kind of hack still needs a proper implementation 51 | NVSDK_NGX_Result NVSDK_NGX_D3D12_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters) 52 | { 53 | *OutParameters = NvParameter::instance()->AllocateParameters(); 54 | return NVSDK_NGX_Result_Success; 55 | } 56 | 57 | //currently it's kind of hack still needs a proper implementation 58 | NVSDK_NGX_Result NVSDK_NGX_D3D12_AllocateParameters(NVSDK_NGX_Parameter** OutParameters) 59 | { 60 | *OutParameters = NvParameter::instance()->AllocateParameters(); 61 | return NVSDK_NGX_Result_Success; 62 | } 63 | 64 | //currently it's kind of hack still needs a proper implementation 65 | NVSDK_NGX_Result NVSDK_NGX_D3D12_DestroyParameters(NVSDK_NGX_Parameter* InParameters) 66 | { 67 | NvParameter::instance()->DeleteParameters((NvParameter*)InParameters); 68 | return NVSDK_NGX_Result_Success; 69 | } 70 | 71 | NVSDK_NGX_Result NVSDK_NGX_D3D12_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, 72 | const NVSDK_NGX_Parameter* InParameters, size_t* OutSizeInBytes) 73 | { 74 | *OutSizeInBytes = ffxFsr2GetScratchMemorySizeDX12(); 75 | return NVSDK_NGX_Result_Success; 76 | } 77 | 78 | NVSDK_NGX_Result NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsCommandList* InCmdList, NVSDK_NGX_Feature InFeatureID, 79 | const NVSDK_NGX_Parameter* InParameters, NVSDK_NGX_Handle** OutHandle) 80 | { 81 | const auto inParams = NvParameter::instance()->Cast((NvParameter*)InParameters); // call to __RTDynamicCast 82 | 83 | ID3D12Device* device; 84 | InCmdList->GetDevice(IID_PPV_ARGS(&device)); 85 | 86 | auto instance = CyberFsrContext::instance(); 87 | auto config = instance->MyConfig; 88 | auto deviceContext = CyberFsrContext::instance()->CreateContext(); 89 | deviceContext->ViewMatrix = ViewMatrixHook::Create(*config); 90 | #ifdef DEBUG_FEATURES 91 | deviceContext->DebugLayer = std::make_unique(device, InCmdList); 92 | #endif 93 | 94 | * OutHandle = &deviceContext->Handle; 95 | 96 | auto initParams = deviceContext->FsrContextDescription; 97 | 98 | const size_t scratchBufferSize = ffxFsr2GetScratchMemorySizeDX12(); 99 | deviceContext->ScratchBuffer = std::vector(scratchBufferSize); 100 | auto scratchBuffer = deviceContext->ScratchBuffer.data(); 101 | 102 | FfxErrorCode errorCode = ffxFsr2GetInterfaceDX12(&initParams.callbacks, device, scratchBuffer, scratchBufferSize); 103 | FFX_ASSERT(errorCode == FFX_OK); 104 | 105 | initParams.device = ffxGetDeviceDX12(device); 106 | initParams.maxRenderSize.width = inParams->Width; 107 | initParams.maxRenderSize.height = inParams->Height; 108 | initParams.displaySize.width = inParams->OutWidth; 109 | initParams.displaySize.height = inParams->OutHeight; 110 | 111 | initParams.flags = 0; 112 | if (config->DepthInverted.value_or(inParams->DepthInverted)) 113 | { 114 | initParams.flags |= FFX_FSR2_ENABLE_DEPTH_INVERTED; 115 | } 116 | if (config->AutoExposure.value_or(inParams->AutoExposure)) 117 | { 118 | initParams.flags |= FFX_FSR2_ENABLE_AUTO_EXPOSURE; 119 | } 120 | if (config->HDR.value_or(inParams->Hdr)) 121 | { 122 | initParams.flags |= FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE; 123 | } 124 | if (config->JitterCancellation.value_or(inParams->JitterMotion)) 125 | { 126 | initParams.flags |= FFX_FSR2_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION; 127 | } 128 | if (config->DisplayResolution.value_or(!inParams->LowRes)) 129 | { 130 | initParams.flags |= FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS; 131 | } 132 | if (config->InfiniteFarPlane.value_or(false)) 133 | { 134 | initParams.flags |= FFX_FSR2_ENABLE_DEPTH_INFINITE; 135 | } 136 | 137 | errorCode = ffxFsr2ContextCreate(&deviceContext->FsrContext, &initParams); 138 | FFX_ASSERT(errorCode == FFX_OK); 139 | 140 | HookSetComputeRootSignature(InCmdList); 141 | 142 | return NVSDK_NGX_Result_Success; 143 | } 144 | 145 | NVSDK_NGX_Result NVSDK_NGX_D3D12_ReleaseFeature(NVSDK_NGX_Handle* InHandle) 146 | { 147 | auto deviceContext = CyberFsrContext::instance()->Contexts[InHandle->Id].get(); 148 | FfxErrorCode errorCode = ffxFsr2ContextDestroy(&deviceContext->FsrContext); 149 | FFX_ASSERT(errorCode == FFX_OK); 150 | CyberFsrContext::instance()->DeleteContext(InHandle); 151 | return NVSDK_NGX_Result_Success; 152 | } 153 | 154 | NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* InFeatureHandle, const NVSDK_NGX_Parameter* InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback) 155 | { 156 | ID3D12RootSignature* orgRootSig = nullptr; 157 | 158 | rootSigMutex.lock(); 159 | if (commandListVector.contains(InCmdList)) 160 | { 161 | orgRootSig = commandListVector[InCmdList]; 162 | } 163 | else 164 | { 165 | printf("Cant find the RootSig\n"); 166 | } 167 | rootSigMutex.unlock(); 168 | 169 | ID3D12Device* device; 170 | InCmdList->GetDevice(IID_PPV_ARGS(&device)); 171 | auto instance = CyberFsrContext::instance(); 172 | auto config = instance->MyConfig; 173 | auto deviceContext = CyberFsrContext::instance()->Contexts[InFeatureHandle->Id].get(); 174 | 175 | if (orgRootSig) 176 | { 177 | const auto inParams = NvParameter::instance()->Cast((NvParameter*)InParameters); // call to __RTDynamicCast 178 | 179 | auto* fsrContext = &deviceContext->FsrContext; 180 | 181 | FfxFsr2DispatchDescription dispatchParameters = {}; 182 | dispatchParameters.commandList = ffxGetCommandListDX12(InCmdList); 183 | dispatchParameters.color = ffxGetResourceDX12(fsrContext, (ID3D12Resource*)inParams->Color, (wchar_t*)L"FSR2_InputColor"); 184 | dispatchParameters.depth = ffxGetResourceDX12(fsrContext, (ID3D12Resource*)inParams->Depth, (wchar_t*)L"FSR2_InputDepth"); 185 | dispatchParameters.motionVectors = ffxGetResourceDX12(fsrContext, (ID3D12Resource*)inParams->MotionVectors, (wchar_t*)L"FSR2_InputMotionVectors"); 186 | dispatchParameters.exposure = ffxGetResourceDX12(fsrContext, (ID3D12Resource*)inParams->ExposureTexture, (wchar_t*)L"FSR2_InputExposure"); 187 | 188 | //Not sure if these two actually work 189 | if (!config->DisableReactiveMask.value_or(false)) 190 | { 191 | dispatchParameters.reactive = ffxGetResourceDX12(fsrContext, (ID3D12Resource*)inParams->InputBiasCurrentColorMask, (wchar_t*)L"FSR2_InputReactiveMap"); 192 | dispatchParameters.transparencyAndComposition = ffxGetResourceDX12(fsrContext, (ID3D12Resource*)inParams->TransparencyMask, (wchar_t*)L"FSR2_TransparencyAndCompositionMap"); 193 | } 194 | 195 | dispatchParameters.output = ffxGetResourceDX12(fsrContext, (ID3D12Resource*)inParams->Output, (wchar_t*)L"FSR2_OutputUpscaledColor", FFX_RESOURCE_STATE_UNORDERED_ACCESS); 196 | 197 | dispatchParameters.jitterOffset.x = inParams->JitterOffsetX; 198 | dispatchParameters.jitterOffset.y = inParams->JitterOffsetY; 199 | 200 | dispatchParameters.motionVectorScale.x = (float)inParams->MVScaleX; 201 | dispatchParameters.motionVectorScale.y = (float)inParams->MVScaleY; 202 | 203 | dispatchParameters.reset = inParams->ResetRender; 204 | 205 | float sharpness = Util::ConvertSharpness(inParams->Sharpness, config->SharpnessRange); 206 | dispatchParameters.enableSharpening = config->EnableSharpening.value_or(inParams->EnableSharpening); 207 | dispatchParameters.sharpness = config->Sharpness.value_or(sharpness); 208 | 209 | //deltatime hax 210 | static double lastFrameTime; 211 | double currentTime = Util::MillisecondsNow(); 212 | double deltaTime = (currentTime - lastFrameTime); 213 | lastFrameTime = currentTime; 214 | 215 | dispatchParameters.frameTimeDelta = (float)deltaTime; 216 | dispatchParameters.preExposure = 1.0f; 217 | dispatchParameters.renderSize.width = inParams->Width; 218 | dispatchParameters.renderSize.height = inParams->Height; 219 | 220 | //Hax Zone 221 | dispatchParameters.cameraFar = deviceContext->ViewMatrix->GetFarPlane(); 222 | dispatchParameters.cameraNear = deviceContext->ViewMatrix->GetNearPlane(); 223 | dispatchParameters.cameraFovAngleVertical = DirectX::XMConvertToRadians(deviceContext->ViewMatrix->GetFov()); 224 | FfxErrorCode errorCode = ffxFsr2ContextDispatch(fsrContext, &dispatchParameters); 225 | FFX_ASSERT(errorCode == FFX_OK); 226 | 227 | InCmdList->SetComputeRootSignature(orgRootSig); 228 | } 229 | #ifdef DEBUG_FEATURES 230 | deviceContext->DebugLayer->AddText(L"DLSS2FSR", DirectX::XMFLOAT2(1.0, 1.0)); 231 | deviceContext->DebugLayer->Render(InCmdList); 232 | #endif 233 | 234 | myCommandList = InCmdList; 235 | 236 | return NVSDK_NGX_Result_Success; 237 | } -------------------------------------------------------------------------------- /CyberFSR/CyberFsrVk.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Config.h" 3 | #include "CyberFsr.h" 4 | #include "DirectXHooks.h" 5 | #include "Util.h" 6 | 7 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) 8 | { 9 | CyberFsrContext::instance()->VulkanDevice = InDevice; 10 | CyberFsrContext::instance()->VulkanInstance = InInstance; 11 | CyberFsrContext::instance()->VulkanPhysicalDevice = InPD; 12 | return NVSDK_NGX_Result_Success; 13 | } 14 | 15 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_ProjectID(const char* InProjectId, NVSDK_NGX_EngineType InEngineType, const char* InEngineVersion, const wchar_t* InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) 16 | { 17 | return NVSDK_NGX_VULKAN_Init(0x1337, InApplicationDataPath, InInstance, InPD, InDevice, InFeatureInfo, InSDKVersion); 18 | } 19 | 20 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_with_ProjectID(const char* InProjectId, NVSDK_NGX_EngineType InEngineType, const char* InEngineVersion, const wchar_t* InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) 21 | { 22 | return NVSDK_NGX_VULKAN_Init(0x1337, InApplicationDataPath, InInstance, InPD, InDevice, InFeatureInfo, InSDKVersion); 23 | } 24 | 25 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Shutdown(void) 26 | { 27 | CyberFsrContext::instance()->VulkanDevice = nullptr; 28 | CyberFsrContext::instance()->VulkanInstance = nullptr; 29 | CyberFsrContext::instance()->VulkanPhysicalDevice = nullptr; 30 | CyberFsrContext::instance()->NvParameterInstance->Params.clear(); 31 | CyberFsrContext::instance()->Contexts.clear(); 32 | return NVSDK_NGX_Result_Success; 33 | } 34 | 35 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Shutdown1(VkDevice InDevice) 36 | { 37 | CyberFsrContext::instance()->VulkanDevice = nullptr; 38 | CyberFsrContext::instance()->VulkanInstance = nullptr; 39 | CyberFsrContext::instance()->VulkanPhysicalDevice = nullptr; 40 | CyberFsrContext::instance()->NvParameterInstance->Params.clear(); 41 | CyberFsrContext::instance()->Contexts.clear(); 42 | return NVSDK_NGX_Result_Success; 43 | } 44 | 45 | NVSDK_NGX_Result NVSDK_NGX_VULKAN_GetParameters(NVSDK_NGX_Parameter** OutParameters) 46 | { 47 | *OutParameters = CyberFsrContext::instance()->NvParameterInstance->AllocateParameters(); 48 | return NVSDK_NGX_Result_Success; 49 | } 50 | 51 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_AllocateParameters(NVSDK_NGX_Parameter** OutParameters) 52 | { 53 | *OutParameters = NvParameter::instance()->AllocateParameters(); 54 | return NVSDK_NGX_Result_Success; 55 | } 56 | 57 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters) 58 | { 59 | *OutParameters = NvParameter::instance()->AllocateParameters(); 60 | return NVSDK_NGX_Result_Success; 61 | } 62 | 63 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_DestroyParameters(NVSDK_NGX_Parameter* InParameters) 64 | { 65 | NvParameter::instance()->DeleteParameters((NvParameter*)InParameters); 66 | return NVSDK_NGX_Result_Success; 67 | } 68 | 69 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter* InParameters, size_t* OutSizeInBytes) 70 | { 71 | auto instance = CyberFsrContext::instance(); 72 | *OutSizeInBytes = ffxFsr2GetScratchMemorySizeVK(instance->VulkanPhysicalDevice); 73 | return NVSDK_NGX_Result_Success; 74 | } 75 | 76 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_CreateFeature(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter* InParameters, NVSDK_NGX_Handle** OutHandle) 77 | { 78 | return NVSDK_NGX_VULKAN_CreateFeature1(CyberFsrContext::instance()->VulkanDevice, InCmdBuffer, InFeatureID, InParameters, OutHandle); 79 | } 80 | 81 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_CreateFeature1(VkDevice InDevice, VkCommandBuffer InCmdList, NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter* InParameters, NVSDK_NGX_Handle** OutHandle) 82 | { 83 | const auto inParams = NvParameter::instance()->Cast((NvParameter*)InParameters); // call to __RTDynamicCast 84 | 85 | auto instance = CyberFsrContext::instance(); 86 | auto& config = instance->MyConfig; 87 | auto deviceContext = instance->CreateContext(); 88 | deviceContext->ViewMatrix = ViewMatrixHook::Create(*config); 89 | #ifdef _DEBUG 90 | deviceContext->DebugLayer = std::make_unique(InDevice, InCmdList); 91 | #endif 92 | 93 | *OutHandle = &deviceContext->Handle; 94 | 95 | auto initParams = deviceContext->FsrContextDescription; 96 | 97 | const size_t scratchBufferSize = ffxFsr2GetScratchMemorySizeVK(instance->VulkanPhysicalDevice); 98 | deviceContext->ScratchBuffer = std::vector(scratchBufferSize); 99 | auto scratchBuffer = deviceContext->ScratchBuffer.data(); 100 | 101 | FfxErrorCode errorCode = ffxFsr2GetInterfaceVK(&initParams.callbacks, scratchBuffer, scratchBufferSize, instance->VulkanPhysicalDevice, vkGetDeviceProcAddr); 102 | FFX_ASSERT(errorCode == FFX_OK); 103 | 104 | initParams.device = ffxGetDeviceVK(InDevice); 105 | initParams.maxRenderSize.width = inParams->Width; 106 | initParams.maxRenderSize.height = inParams->Height; 107 | initParams.displaySize.width = inParams->OutWidth; 108 | initParams.displaySize.height = inParams->OutHeight; 109 | initParams.flags = (inParams->DepthInverted) ? FFX_FSR2_ENABLE_DEPTH_INVERTED : 0 110 | | (inParams->AutoExposure) ? FFX_FSR2_ENABLE_AUTO_EXPOSURE : 0 111 | | (inParams->Hdr) ? FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE : 0 112 | | (inParams->JitterMotion) ? FFX_FSR2_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION : 0 113 | | (!inParams->LowRes) ? FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS : 0; 114 | 115 | initParams.flags = 0; 116 | if (config->DepthInverted.value_or(inParams->DepthInverted)) 117 | { 118 | initParams.flags |= FFX_FSR2_ENABLE_DEPTH_INVERTED; 119 | } 120 | if (config->AutoExposure.value_or(inParams->AutoExposure)) 121 | { 122 | initParams.flags |= FFX_FSR2_ENABLE_AUTO_EXPOSURE; 123 | } 124 | if (config->HDR.value_or(inParams->Hdr)) 125 | { 126 | initParams.flags |= FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE; 127 | } 128 | if (config->JitterCancellation.value_or(inParams->JitterMotion)) 129 | { 130 | initParams.flags |= FFX_FSR2_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION; 131 | } 132 | if (config->DisplayResolution.value_or(!inParams->LowRes)) 133 | { 134 | initParams.flags |= FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS; 135 | } 136 | 137 | errorCode = ffxFsr2ContextCreate(&deviceContext->FsrContext, &initParams); 138 | FFX_ASSERT(errorCode == FFX_OK); 139 | return NVSDK_NGX_Result_Success; 140 | } 141 | 142 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_ReleaseFeature(NVSDK_NGX_Handle* InHandle) 143 | { 144 | auto deviceContext = CyberFsrContext::instance()->Contexts[InHandle->Id].get(); 145 | FfxErrorCode errorCode = ffxFsr2ContextDestroy(&deviceContext->FsrContext); 146 | FFX_ASSERT(errorCode == FFX_OK); 147 | CyberFsrContext::instance()->DeleteContext(InHandle); 148 | return NVSDK_NGX_Result_Success; 149 | } 150 | 151 | NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_EvaluateFeature(VkCommandBuffer InCmdList, const NVSDK_NGX_Handle* InFeatureHandle, const NVSDK_NGX_Parameter* InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback) 152 | { 153 | auto instance = CyberFsrContext::instance(); 154 | auto& config = instance->MyConfig; 155 | auto deviceContext = CyberFsrContext::instance()->Contexts[InFeatureHandle->Id].get(); 156 | const auto inParams = NvParameter::instance()->Cast((NvParameter*)InParameters); // call to __RTDynamicCast 157 | 158 | auto color = (NVSDK_NGX_Resource_VK*)inParams->Color; 159 | auto depth = (NVSDK_NGX_Resource_VK*)inParams->Depth; 160 | auto motionVectors = (NVSDK_NGX_Resource_VK*)inParams->MotionVectors; 161 | auto exposureTexture = (NVSDK_NGX_Resource_VK*)inParams->ExposureTexture; 162 | auto inputBiasColorMask = (NVSDK_NGX_Resource_VK*)inParams->InputBiasCurrentColorMask; 163 | auto transparencyMask = (NVSDK_NGX_Resource_VK*)inParams->TransparencyMask; 164 | auto output = (NVSDK_NGX_Resource_VK*)inParams->Output; 165 | 166 | auto* fsrContext = &deviceContext->FsrContext; 167 | FfxFsr2DispatchDescription dispatchParameters = {}; 168 | dispatchParameters.commandList = ffxGetCommandListVK(InCmdList); 169 | if (color) 170 | dispatchParameters.color = ffxGetTextureResourceVK(fsrContext, color->Resource.ImageViewInfo.Image, color->Resource.ImageViewInfo.ImageView, color->Resource.ImageViewInfo.Width, color->Resource.ImageViewInfo.Height, color->Resource.ImageViewInfo.Format, (wchar_t*)L"FSR2_InputColor"); 171 | if (depth) 172 | dispatchParameters.depth = ffxGetTextureResourceVK(fsrContext, depth->Resource.ImageViewInfo.Image, depth->Resource.ImageViewInfo.ImageView, depth->Resource.ImageViewInfo.Width, depth->Resource.ImageViewInfo.Height, depth->Resource.ImageViewInfo.Format, (wchar_t*)L"FSR2_InputDepth"); 173 | if (motionVectors) 174 | dispatchParameters.motionVectors = ffxGetTextureResourceVK(fsrContext, motionVectors->Resource.ImageViewInfo.Image, motionVectors->Resource.ImageViewInfo.ImageView, motionVectors->Resource.ImageViewInfo.Width, motionVectors->Resource.ImageViewInfo.Height, motionVectors->Resource.ImageViewInfo.Format, (wchar_t*)L"FSR2_InputMotionVectors"); 175 | if (exposureTexture) 176 | dispatchParameters.exposure = ffxGetTextureResourceVK(fsrContext, exposureTexture->Resource.ImageViewInfo.Image, exposureTexture->Resource.ImageViewInfo.ImageView, exposureTexture->Resource.ImageViewInfo.Width, exposureTexture->Resource.ImageViewInfo.Height, exposureTexture->Resource.ImageViewInfo.Format, (wchar_t*)L"FSR2_InputExposure"); 177 | if (inputBiasColorMask) 178 | dispatchParameters.reactive = ffxGetTextureResourceVK(fsrContext, inputBiasColorMask->Resource.ImageViewInfo.Image, inputBiasColorMask->Resource.ImageViewInfo.ImageView, inputBiasColorMask->Resource.ImageViewInfo.Width, inputBiasColorMask->Resource.ImageViewInfo.Height, inputBiasColorMask->Resource.ImageViewInfo.Format, (wchar_t*)L"FSR2_InputReactiveMap"); 179 | if (transparencyMask) 180 | dispatchParameters.transparencyAndComposition = ffxGetTextureResourceVK(fsrContext, transparencyMask->Resource.ImageViewInfo.Image, transparencyMask->Resource.ImageViewInfo.ImageView, transparencyMask->Resource.ImageViewInfo.Width, transparencyMask->Resource.ImageViewInfo.Height, transparencyMask->Resource.ImageViewInfo.Format, (wchar_t*)L"FSR2_TransparencyAndCompositionMap"); 181 | if (output) 182 | dispatchParameters.output = ffxGetTextureResourceVK(fsrContext, output->Resource.ImageViewInfo.Image, output->Resource.ImageViewInfo.ImageView, output->Resource.ImageViewInfo.Width, output->Resource.ImageViewInfo.Height, output->Resource.ImageViewInfo.Format, (wchar_t*)L"FSR2_OutputUpscaledColor", FFX_RESOURCE_STATE_UNORDERED_ACCESS); 183 | 184 | dispatchParameters.jitterOffset.x = inParams->JitterOffsetX; 185 | dispatchParameters.jitterOffset.y = inParams->JitterOffsetY; 186 | dispatchParameters.motionVectorScale.x = (float)inParams->MVScaleX; 187 | dispatchParameters.motionVectorScale.y = (float)inParams->MVScaleY; 188 | 189 | dispatchParameters.reset = inParams->ResetRender; 190 | 191 | float sharpness = Util::ConvertSharpness(inParams->Sharpness, config->SharpnessRange); 192 | dispatchParameters.enableSharpening = config->EnableSharpening.value_or(inParams->EnableSharpening); 193 | dispatchParameters.sharpness = config->Sharpness.value_or(sharpness); 194 | 195 | static double lastFrameTime = 0.0; 196 | double currentTime = Util::MillisecondsNow(); 197 | double deltaTime = (currentTime - lastFrameTime); 198 | lastFrameTime = currentTime; 199 | 200 | dispatchParameters.frameTimeDelta = (float)deltaTime; 201 | dispatchParameters.preExposure = 1.0f; 202 | dispatchParameters.renderSize.width = inParams->Width; 203 | dispatchParameters.renderSize.height = inParams->Height; 204 | 205 | dispatchParameters.cameraFar = deviceContext->ViewMatrix->GetFarPlane(); 206 | dispatchParameters.cameraNear = deviceContext->ViewMatrix->GetNearPlane(); 207 | dispatchParameters.cameraFovAngleVertical = DirectX::XMConvertToRadians(deviceContext->ViewMatrix->GetFov()); 208 | FfxErrorCode errorCode = ffxFsr2ContextDispatch(fsrContext, &dispatchParameters); 209 | FFX_ASSERT(errorCode == FFX_OK); 210 | #ifdef _DEBUG 211 | deviceContext->DebugLayer->Render(InCmdList); 212 | #endif 213 | 214 | return NVSDK_NGX_Result_Success; 215 | } -------------------------------------------------------------------------------- /CyberFSR/DebugOverlay.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "DebugOverlay.h" 3 | 4 | DebugOverlay::DebugOverlay(ID3D12Device* device, ID3D12GraphicsCommandList* cmdList) 5 | { 6 | } 7 | 8 | DebugOverlay::DebugOverlay(VkDevice InDevice, VkCommandBuffer InCmdList) 9 | { 10 | } 11 | 12 | DebugOverlay::~DebugOverlay() 13 | { 14 | } 15 | 16 | void DebugOverlay::Render(ID3D12GraphicsCommandList* cmdList) 17 | { 18 | } 19 | 20 | void DebugOverlay::Render(VkCommandBuffer cmdList) 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /CyberFSR/DebugOverlay.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class DebugOverlay 3 | { 4 | public: 5 | DebugOverlay(ID3D12Device* device, ID3D12GraphicsCommandList* cmdList); 6 | DebugOverlay(VkDevice InDevice, VkCommandBuffer InCmdList); 7 | ~DebugOverlay(); 8 | void Render(ID3D12GraphicsCommandList* cmdList); 9 | void Render(VkCommandBuffer cmdList); 10 | }; -------------------------------------------------------------------------------- /CyberFSR/DirectXHooks.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Util.h" 3 | #include "DirectXHooks.h" 4 | #include 5 | 6 | /* 7 | Cyberpunk doesn't reset the ComputeRootSignature after running DLSS. 8 | This is fine for DLSS itself because they only use CUDA stuff but breaks everything for implementations that use compute shaders 9 | 10 | The only solution to bypass this problem in a safe manner is to hook the CreateCommandQueue function of the CommandLists VTable we get in NVSDK_NGX_D3D12_CreateFeature and after that hook the SetComputeRootSignature function of every created CommandQueue. 11 | This allows us to keep track of every ComputeRootSignature and match the RootSignature with the CommandList we get in NVSDK_NGX_D3D12_EvaluateFeature to restore it after FSR2 completes. 12 | */ 13 | 14 | SETCOMPUTEROOTSIGNATURE oSetComputeRootSignature = nullptr; 15 | 16 | ID3D12CommandList* myCommandList = nullptr; 17 | 18 | ankerl::unordered_dense::map commandListVector; 19 | 20 | std::mutex rootSigMutex; 21 | 22 | #define INITIAL_THREAD_CAPACITY 128 23 | 24 | HANDLE g_hHeap = NULL; 25 | 26 | #define THREAD_ACCESS \ 27 | (THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION | THREAD_SET_CONTEXT) 28 | 29 | typedef struct _FROZEN_THREADS 30 | { 31 | LPDWORD pItems; // Data heap 32 | UINT capacity; // Size of allocated data heap, items 33 | UINT size; // Actual number of data items 34 | } FROZEN_THREADS, * PFROZEN_THREADS; 35 | 36 | static BOOL EnumerateThreads(PFROZEN_THREADS pThreads) 37 | { 38 | BOOL succeeded = FALSE; 39 | 40 | HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 41 | if (hSnapshot != INVALID_HANDLE_VALUE) 42 | { 43 | THREADENTRY32 te; 44 | te.dwSize = sizeof(THREADENTRY32); 45 | if (Thread32First(hSnapshot, &te)) 46 | { 47 | succeeded = TRUE; 48 | do 49 | { 50 | if (te.dwSize >= (FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(DWORD)) 51 | && te.th32OwnerProcessID == GetCurrentProcessId() 52 | && te.th32ThreadID != GetCurrentThreadId()) 53 | { 54 | if (pThreads->pItems == NULL) 55 | { 56 | pThreads->capacity = INITIAL_THREAD_CAPACITY; 57 | pThreads->pItems 58 | = (LPDWORD)HeapAlloc(g_hHeap, 0, pThreads->capacity * sizeof(DWORD)); 59 | if (pThreads->pItems == NULL) 60 | { 61 | succeeded = FALSE; 62 | break; 63 | } 64 | } 65 | else if (pThreads->size >= pThreads->capacity) 66 | { 67 | pThreads->capacity *= 2; 68 | LPDWORD p = (LPDWORD)HeapReAlloc( 69 | g_hHeap, 0, pThreads->pItems, pThreads->capacity * sizeof(DWORD)); 70 | if (p == NULL) 71 | { 72 | succeeded = FALSE; 73 | break; 74 | } 75 | 76 | pThreads->pItems = p; 77 | } 78 | pThreads->pItems[pThreads->size++] = te.th32ThreadID; 79 | } 80 | 81 | te.dwSize = sizeof(THREADENTRY32); 82 | } while (Thread32Next(hSnapshot, &te)); 83 | 84 | if (succeeded && GetLastError() != ERROR_NO_MORE_FILES) 85 | succeeded = FALSE; 86 | 87 | if (!succeeded && pThreads->pItems != NULL) 88 | { 89 | HeapFree(g_hHeap, 0, pThreads->pItems); 90 | pThreads->pItems = NULL; 91 | } 92 | } 93 | CloseHandle(hSnapshot); 94 | } 95 | 96 | return succeeded; 97 | } 98 | 99 | static bool Freeze(PFROZEN_THREADS pThreads) 100 | { 101 | 102 | pThreads->pItems = NULL; 103 | pThreads->capacity = 0; 104 | pThreads->size = 0; 105 | if (!EnumerateThreads(pThreads)) 106 | { 107 | return false; 108 | } 109 | else if (pThreads->pItems != NULL) 110 | { 111 | UINT i; 112 | for (i = 0; i < pThreads->size; ++i) 113 | { 114 | HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]); 115 | if (hThread != NULL) 116 | { 117 | SuspendThread(hThread); 118 | CloseHandle(hThread); 119 | } 120 | } 121 | } 122 | 123 | return true; 124 | } 125 | 126 | static VOID Unfreeze(PFROZEN_THREADS pThreads) 127 | { 128 | if (pThreads->pItems != NULL) 129 | { 130 | UINT i; 131 | for (i = 0; i < pThreads->size; ++i) 132 | { 133 | HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]); 134 | if (hThread != NULL) 135 | { 136 | ResumeThread(hThread); 137 | CloseHandle(hThread); 138 | } 139 | } 140 | 141 | HeapFree(g_hHeap, 0, pThreads->pItems); 142 | } 143 | } 144 | 145 | 146 | void hSetComputeRootSignature(ID3D12GraphicsCommandList* commandList, ID3D12RootSignature* pRootSignature) 147 | { 148 | rootSigMutex.lock(); 149 | commandListVector[commandList] = pRootSignature; 150 | rootSigMutex.unlock(); 151 | 152 | return oSetComputeRootSignature(commandList, pRootSignature); 153 | } 154 | 155 | void HookSetComputeRootSignature(ID3D12GraphicsCommandList* InCmdList) 156 | { 157 | constexpr int offset = 0xE8 / sizeof(void*); 158 | 159 | void** cmdListVTable = *reinterpret_cast(InCmdList); 160 | const auto computeRootSigFuncVTable = reinterpret_cast(cmdListVTable + offset); 161 | 162 | if (oSetComputeRootSignature == nullptr) 163 | { 164 | oSetComputeRootSignature = *computeRootSigFuncVTable; 165 | 166 | if (g_hHeap == NULL) 167 | { 168 | g_hHeap = HeapCreate(0, 0, 0); 169 | } 170 | 171 | DWORD oldProtect; 172 | FROZEN_THREADS threads; 173 | Freeze(&threads); 174 | VirtualProtect(computeRootSigFuncVTable, sizeof(void*), PAGE_READWRITE, &oldProtect); 175 | *computeRootSigFuncVTable = &hSetComputeRootSignature; 176 | VirtualProtect(computeRootSigFuncVTable, sizeof(void*), oldProtect, nullptr); 177 | FlushInstructionCache(GetCurrentProcess(), computeRootSigFuncVTable, sizeof(void*)); 178 | Unfreeze(&threads); 179 | } 180 | } -------------------------------------------------------------------------------- /CyberFSR/DirectXHooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pch.h" 3 | 4 | typedef void(__fastcall* SETCOMPUTEROOTSIGNATURE)(ID3D12GraphicsCommandList* commandList, ID3D12RootSignature* pRootSignature); 5 | 6 | extern ID3D12CommandList* myCommandList; 7 | 8 | extern ankerl::unordered_dense::map commandListVector; 9 | 10 | extern std::mutex rootSigMutex; 11 | 12 | void HookSetComputeRootSignature(ID3D12GraphicsCommandList* InCmdList); 13 | -------------------------------------------------------------------------------- /CyberFSR/NvParameter.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Config.h" 3 | #include "Util.h" 4 | #include "NvParameter.h" 5 | #include "CyberFsr.h" 6 | 7 | void NvParameter::Set(const char* InName, unsigned long long InValue) 8 | { 9 | auto value = (unsigned long long*) & InValue; 10 | Set_Internal(InName, *value, NvULL); 11 | } 12 | 13 | void NvParameter::Set(const char* InName, float InValue) 14 | { 15 | auto value = (unsigned long long*) & InValue; 16 | Set_Internal(InName, *value, NvFloat); 17 | } 18 | 19 | void NvParameter::Set(const char* InName, double InValue) 20 | { 21 | auto value = (unsigned long long*) & InValue; 22 | Set_Internal(InName, *value, NvDouble); 23 | } 24 | 25 | void NvParameter::Set(const char* InName, unsigned int InValue) 26 | { 27 | auto value = (unsigned long long*) & InValue; 28 | Set_Internal(InName, *value, NvUInt); 29 | } 30 | 31 | void NvParameter::Set(const char* InName, int InValue) 32 | { 33 | auto value = (unsigned long long*) & InValue; 34 | Set_Internal(InName, *value, NvInt); 35 | } 36 | 37 | void NvParameter::Set(const char* InName, ID3D11Resource* InValue) 38 | { 39 | auto value = (unsigned long long*) & InValue; 40 | Set_Internal(InName, *value, NvD3D11Resource); 41 | } 42 | 43 | void NvParameter::Set(const char* InName, ID3D12Resource* InValue) 44 | { 45 | auto value = (unsigned long long*) & InValue; 46 | Set_Internal(InName, *value, NvD3D12Resource); 47 | } 48 | 49 | void NvParameter::Set(const char* InName, void* InValue) 50 | { 51 | auto value = (unsigned long long*) & InValue; 52 | Set_Internal(InName, *value, NvVoidPtr); 53 | } 54 | 55 | NVSDK_NGX_Result NvParameter::Get(const char* InName, unsigned long long* OutValue) const 56 | { 57 | return Get_Internal(InName, (unsigned long long*)OutValue, NvULL); 58 | } 59 | 60 | NVSDK_NGX_Result NvParameter::Get(const char* InName, float* OutValue) const 61 | { 62 | return Get_Internal(InName, (unsigned long long*)OutValue, NvFloat); 63 | } 64 | 65 | NVSDK_NGX_Result NvParameter::Get(const char* InName, double* OutValue) const 66 | { 67 | return Get_Internal(InName, (unsigned long long*)OutValue, NvDouble); 68 | } 69 | 70 | NVSDK_NGX_Result NvParameter::Get(const char* InName, unsigned int* OutValue) const 71 | { 72 | return Get_Internal(InName, (unsigned long long*)OutValue, NvUInt); 73 | } 74 | 75 | NVSDK_NGX_Result NvParameter::Get(const char* InName, int* OutValue) const 76 | { 77 | return Get_Internal(InName, (unsigned long long*)OutValue, NvInt); 78 | } 79 | 80 | NVSDK_NGX_Result NvParameter::Get(const char* InName, ID3D11Resource** OutValue) const 81 | { 82 | return Get_Internal(InName, (unsigned long long*)OutValue, NvD3D11Resource); 83 | } 84 | 85 | NVSDK_NGX_Result NvParameter::Get(const char* InName, ID3D12Resource** OutValue) const 86 | { 87 | return Get_Internal(InName, (unsigned long long*)OutValue, NvD3D12Resource); 88 | } 89 | 90 | NVSDK_NGX_Result NvParameter::Get(const char* InName, void** OutValue) const 91 | { 92 | return Get_Internal(InName, (unsigned long long*)OutValue, NvVoidPtr); 93 | } 94 | 95 | void NvParameter::Reset() 96 | { 97 | } 98 | 99 | void NvParameter::Set_Internal(const char* InName, unsigned long long InValue, NvParameterType ParameterType) 100 | { 101 | auto inValueFloat = (float*)&InValue; 102 | auto inValueInt = (int*)&InValue; 103 | auto inValueDouble = (double*)&InValue; 104 | auto inValueUInt = (unsigned int*)&InValue; 105 | //Includes DirectX Resources 106 | auto inValuePtr = (void*)InValue; 107 | 108 | switch (Util::NvParameterToEnum(InName)) 109 | { 110 | case Util::NvParameter::MV_Scale_X: 111 | MVScaleX = *inValueFloat; 112 | break; 113 | case Util::NvParameter::MV_Scale_Y: 114 | MVScaleY = *inValueFloat; 115 | break; 116 | case Util::NvParameter::Jitter_Offset_X: 117 | JitterOffsetX = *inValueFloat; 118 | break; 119 | case Util::NvParameter::Jitter_Offset_Y: 120 | JitterOffsetY = *inValueFloat; 121 | break; 122 | case Util::NvParameter::Sharpness: 123 | Sharpness = *inValueFloat; 124 | break; 125 | case Util::NvParameter::Width: 126 | Width = *inValueInt; 127 | break; 128 | case Util::NvParameter::Height: 129 | Height = *inValueInt; 130 | break; 131 | case Util::NvParameter::DLSS_Render_Subrect_Dimensions_Width: 132 | Width = *inValueInt; 133 | break; 134 | case Util::NvParameter::DLSS_Render_Subrect_Dimensions_Height: 135 | Height = *inValueInt; 136 | break; 137 | case Util::NvParameter::PerfQualityValue: 138 | PerfQualityValue = static_cast(*inValueInt); 139 | break; 140 | case Util::NvParameter::RTXValue: 141 | RTXValue = *inValueInt; 142 | break; 143 | case Util::NvParameter::FreeMemOnReleaseFeature: 144 | FreeMemOnReleaseFeature = *inValueInt; 145 | break; 146 | case Util::NvParameter::CreationNodeMask: 147 | CreationNodeMask = *inValueInt; 148 | break; 149 | case Util::NvParameter::VisibilityNodeMask: 150 | VisibilityNodeMask = *inValueInt; 151 | break; 152 | case Util::NvParameter::Reset: 153 | ResetRender = *inValueInt; 154 | break; 155 | case Util::NvParameter::OutWidth: 156 | OutWidth = *inValueInt; 157 | break; 158 | case Util::NvParameter::OutHeight: 159 | OutHeight = *inValueInt; 160 | break; 161 | case Util::NvParameter::DLSS_Feature_Create_Flags: 162 | Hdr = *inValueInt & NVSDK_NGX_DLSS_Feature_Flags_IsHDR; 163 | EnableSharpening = *inValueInt & NVSDK_NGX_DLSS_Feature_Flags_DoSharpening; 164 | DepthInverted = *inValueInt & NVSDK_NGX_DLSS_Feature_Flags_DepthInverted; 165 | JitterMotion = *inValueInt & NVSDK_NGX_DLSS_Feature_Flags_MVJittered; 166 | LowRes = *inValueInt & NVSDK_NGX_DLSS_Feature_Flags_MVLowRes; 167 | AutoExposure = *inValueInt & NVSDK_NGX_DLSS_Feature_Flags_AutoExposure; 168 | break; 169 | case Util::NvParameter::DLSS_Input_Bias_Current_Color_Mask: 170 | InputBiasCurrentColorMask = inValuePtr; 171 | if (InputBiasCurrentColorMask && ParameterType == NvParameterType::NvD3D12Resource) 172 | ((ID3D12Resource*)InputBiasCurrentColorMask)->SetName(L"Color"); 173 | break; 174 | case Util::NvParameter::Color: 175 | Color = inValuePtr; 176 | if (Color && ParameterType == NvParameterType::NvD3D12Resource) 177 | ((ID3D12Resource*)Color)->SetName(L"Color"); 178 | break; 179 | case Util::NvParameter::Depth: 180 | Depth = inValuePtr; 181 | if (Depth && ParameterType == NvParameterType::NvD3D12Resource) 182 | ((ID3D12Resource*)Depth)->SetName(L"Depth"); 183 | break; 184 | case Util::NvParameter::MotionVectors: 185 | MotionVectors = inValuePtr; 186 | if (MotionVectors && ParameterType == NvParameterType::NvD3D12Resource) 187 | ((ID3D12Resource*)MotionVectors)->SetName(L"MotionVectors"); 188 | break; 189 | case Util::NvParameter::Output: 190 | Output = inValuePtr; 191 | if (Output && ParameterType == NvParameterType::NvD3D12Resource) 192 | ((ID3D12Resource*)Output)->SetName(L"Output"); 193 | break; 194 | case Util::NvParameter::TransparencyMask: 195 | TransparencyMask = inValuePtr; 196 | if (TransparencyMask && ParameterType == NvParameterType::NvD3D12Resource) 197 | ((ID3D12Resource*)TransparencyMask)->SetName(L"TransparencyMask"); 198 | break; 199 | case Util::NvParameter::ExposureTexture: 200 | ExposureTexture = inValuePtr; 201 | if (ExposureTexture && ParameterType == NvParameterType::NvD3D12Resource) 202 | ((ID3D12Resource*)ExposureTexture)->SetName(L"ExposureTexture"); 203 | break; 204 | } 205 | } 206 | 207 | NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_DLSS_GetOptimalSettingsCallback(NVSDK_NGX_Parameter* InParams); 208 | NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_DLSS_GetStatsCallback(NVSDK_NGX_Parameter* InParams); 209 | 210 | NVSDK_NGX_Result NvParameter::Get_Internal(const char* InName, unsigned long long* OutValue, NvParameterType ParameterType) const 211 | { 212 | auto outValueFloat = (float*)OutValue; 213 | auto outValueInt = (int*)OutValue; 214 | auto outValueDouble = (double*)OutValue; 215 | auto outValueUInt = (unsigned int*)OutValue; 216 | auto outValueULL = (unsigned long long*)OutValue; 217 | //Includes DirectX Resources 218 | auto outValuePtr = (void**)OutValue; 219 | 220 | switch (Util::NvParameterToEnum(InName)) 221 | { 222 | case Util::NvParameter::Sharpness: 223 | *outValueFloat = Sharpness; 224 | break; 225 | case Util::NvParameter::SuperSampling_Available: 226 | *outValueInt = true; 227 | break; 228 | case Util::NvParameter::SuperSampling_FeatureInitResult: 229 | *outValueInt = NVSDK_NGX_Result_Success; 230 | break; 231 | case Util::NvParameter::SuperSampling_NeedsUpdatedDriver: 232 | *outValueInt = 0; 233 | break; 234 | case Util::NvParameter::SuperSampling_MinDriverVersionMinor: 235 | case Util::NvParameter::SuperSampling_MinDriverVersionMajor: 236 | *outValueInt = 0; 237 | break; 238 | case Util::NvParameter::DLSS_Render_Subrect_Dimensions_Width: 239 | *outValueInt = Width; 240 | break; 241 | case Util::NvParameter::DLSS_Render_Subrect_Dimensions_Height: 242 | *outValueInt = Height; 243 | break; 244 | case Util::NvParameter::OutWidth: 245 | *outValueInt = OutWidth; 246 | break; 247 | case Util::NvParameter::OutHeight: 248 | *outValueInt = OutHeight; 249 | break; 250 | case Util::NvParameter::DLSS_Get_Dynamic_Max_Render_Width: 251 | *outValueInt = Width; 252 | break; 253 | case Util::NvParameter::DLSS_Get_Dynamic_Max_Render_Height: 254 | *outValueInt = Height; 255 | break; 256 | case Util::NvParameter::DLSS_Get_Dynamic_Min_Render_Width: 257 | *outValueInt = OutWidth; 258 | break; 259 | case Util::NvParameter::DLSS_Get_Dynamic_Min_Render_Height: 260 | *outValueInt = OutHeight; 261 | break; 262 | case Util::NvParameter::DLSSOptimalSettingsCallback: 263 | *outValuePtr = NVSDK_NGX_DLSS_GetOptimalSettingsCallback; 264 | break; 265 | case Util::NvParameter::DLSSGetStatsCallback: 266 | *outValuePtr = NVSDK_NGX_DLSS_GetStatsCallback; 267 | break; 268 | case Util::NvParameter::SizeInBytes: 269 | *outValueULL = 0x1337; //Dummy value 270 | break; 271 | case Util::NvParameter::OptLevel: 272 | *outValueInt = 0; //Dummy value 273 | break; 274 | case Util::NvParameter::IsDevSnippetBranch: 275 | *outValueInt = 0; //Dummy value 276 | break; 277 | default: 278 | return NVSDK_NGX_Result_Fail; 279 | } 280 | 281 | return NVSDK_NGX_Result_Success; 282 | } 283 | 284 | // EvaluateRenderScale helper 285 | inline FfxFsr2QualityMode DLSS2FSR2QualityTable(const NVSDK_NGX_PerfQuality_Value input) 286 | { 287 | FfxFsr2QualityMode output; 288 | 289 | switch (input) 290 | { 291 | case NVSDK_NGX_PerfQuality_Value_UltraPerformance: 292 | output = FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE; 293 | break; 294 | case NVSDK_NGX_PerfQuality_Value_MaxPerf: 295 | output = FFX_FSR2_QUALITY_MODE_PERFORMANCE; 296 | break; 297 | case NVSDK_NGX_PerfQuality_Value_Balanced: 298 | output = FFX_FSR2_QUALITY_MODE_BALANCED; 299 | break; 300 | case NVSDK_NGX_PerfQuality_Value_MaxQuality: 301 | output = FFX_FSR2_QUALITY_MODE_QUALITY; 302 | break; 303 | case NVSDK_NGX_PerfQuality_Value_UltraQuality: 304 | default: 305 | output = (FfxFsr2QualityMode)5; //Set out-of-range value for non-existing fsr ultra quality mode 306 | break; 307 | } 308 | 309 | return output; 310 | } 311 | 312 | // EvaluateRenderScale helper 313 | inline std::optional GetQualityOverrideRatio(const NVSDK_NGX_PerfQuality_Value input, const std::shared_ptr config) 314 | { 315 | std::optional output; 316 | 317 | if (!(config->QualityRatioOverrideEnabled.has_value() && config->QualityRatioOverrideEnabled)) 318 | return output; // override not enabled 319 | 320 | switch (input) 321 | { 322 | case NVSDK_NGX_PerfQuality_Value_UltraPerformance: 323 | output = config->QualityRatio_UltraPerformance; 324 | break; 325 | case NVSDK_NGX_PerfQuality_Value_MaxPerf: 326 | output = config->QualityRatio_Performance; 327 | break; 328 | case NVSDK_NGX_PerfQuality_Value_Balanced: 329 | output = config->QualityRatio_Balanced; 330 | break; 331 | case NVSDK_NGX_PerfQuality_Value_MaxQuality: 332 | output = config->QualityRatio_Quality; 333 | break; 334 | case NVSDK_NGX_PerfQuality_Value_UltraQuality: 335 | output = config->QualityRatio_UltraQuality; 336 | break; 337 | default: 338 | // no correlated value, add some logging? 339 | break; 340 | } 341 | return output; 342 | } 343 | 344 | void NvParameter::EvaluateRenderScale() 345 | { 346 | const std::shared_ptr config = CyberFsrContext::instance()->MyConfig; 347 | 348 | const std::optional QualityRatio = GetQualityOverrideRatio(PerfQualityValue, config); 349 | 350 | if (QualityRatio.has_value()) { 351 | OutHeight = (unsigned int)((float)Height / QualityRatio.value()); 352 | OutWidth = (unsigned int)((float)Width / QualityRatio.value()); 353 | } 354 | else { 355 | const FfxFsr2QualityMode fsrQualityMode = DLSS2FSR2QualityTable(PerfQualityValue); 356 | 357 | if (fsrQualityMode < 5) { 358 | ffxFsr2GetRenderResolutionFromQualityMode(&OutWidth, &OutHeight, Width, Height, fsrQualityMode); 359 | } 360 | else { 361 | //Ultra Quality Mode 362 | OutHeight = Height; 363 | OutWidth = Width; 364 | } 365 | } 366 | } 367 | 368 | NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_DLSS_GetOptimalSettingsCallback(NVSDK_NGX_Parameter* InParams) 369 | { 370 | auto params = NvParameter::instance()->Cast((NvParameter*)InParams); // call to __RTDynamicCast 371 | params->EvaluateRenderScale(); 372 | return NVSDK_NGX_Result_Success; 373 | } 374 | 375 | NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_DLSS_GetStatsCallback(NVSDK_NGX_Parameter* InParams) 376 | { 377 | //Somehow check for allocated memory 378 | //Then set values: SizeInBytes, OptLevel, IsDevSnippetBranch 379 | return NVSDK_NGX_Result_Success; 380 | } -------------------------------------------------------------------------------- /CyberFSR/NvParameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pch.h" 3 | 4 | enum NvParameterType { 5 | NvInt, 6 | NvFloat, 7 | NvDouble, 8 | NvUInt, 9 | NvULL, 10 | NvD3D11Resource, 11 | NvD3D12Resource, 12 | NvVoidPtr 13 | }; 14 | 15 | struct NvParameter : NVSDK_NGX_Parameter 16 | { 17 | unsigned int Width{}, Height{}, OutWidth{}, OutHeight{}; 18 | NVSDK_NGX_PerfQuality_Value PerfQualityValue = NVSDK_NGX_PerfQuality_Value_Balanced; 19 | bool RTXValue{}, FreeMemOnReleaseFeature{}; 20 | int CreationNodeMask{}, VisibilityNodeMask{}, OptLevel{}, IsDevSnippetBranch{}; 21 | float Sharpness = 1.0f; 22 | bool ResetRender{}; 23 | float MVScaleX = 1.0, MVScaleY = 1.0; 24 | float JitterOffsetX{}, JitterOffsetY{}; 25 | 26 | long long SizeInBytes{}; 27 | 28 | bool DepthInverted{}, AutoExposure{}, Hdr{}, EnableSharpening{}, JitterMotion{}, LowRes{}; 29 | 30 | //external Resources 31 | void* InputBiasCurrentColorMask{}; 32 | void* Color{}; 33 | void* Depth{}; 34 | void* MotionVectors{}; 35 | void* Output{}; 36 | void* TransparencyMask{}; 37 | void* ExposureTexture{}; 38 | 39 | virtual void Set(const char* InName, unsigned long long InValue) override; 40 | virtual void Set(const char* InName, float InValue) override; 41 | virtual void Set(const char* InName, double InValue) override; 42 | virtual void Set(const char* InName, unsigned int InValue) override; 43 | virtual void Set(const char* InName, int InValue) override; 44 | virtual void Set(const char* InName, ID3D11Resource* InValue) override; 45 | virtual void Set(const char* InName, ID3D12Resource* InValue) override; 46 | virtual void Set(const char* InName, void* InValue) override; 47 | virtual NVSDK_NGX_Result Get(const char* InName, unsigned long long* OutValue) const override; 48 | virtual NVSDK_NGX_Result Get(const char* InName, float* OutValue) const override; 49 | virtual NVSDK_NGX_Result Get(const char* InName, double* OutValue) const override; 50 | virtual NVSDK_NGX_Result Get(const char* InName, unsigned int* OutValue) const override; 51 | virtual NVSDK_NGX_Result Get(const char* InName, int* OutValue) const override; 52 | virtual NVSDK_NGX_Result Get(const char* InName, ID3D11Resource** OutValue) const override; 53 | virtual NVSDK_NGX_Result Get(const char* InName, ID3D12Resource** OutValue) const override; 54 | virtual NVSDK_NGX_Result Get(const char* InName, void** OutValue) const override; 55 | virtual void Reset() override; 56 | 57 | void Set_Internal(const char* InName, unsigned long long InValue, NvParameterType ParameterType); 58 | NVSDK_NGX_Result Get_Internal(const char* InName, unsigned long long* OutValue, NvParameterType ParameterType) const; 59 | 60 | void EvaluateRenderScale(); 61 | 62 | inline NvParameter* Cast(NVSDK_NGX_Parameter* Parameter) 63 | { 64 | return dynamic_cast(Parameter); // will compile into __RTDynamicCast 65 | } 66 | 67 | std::vector> Params; 68 | 69 | __declspec(noinline) NvParameter* AllocateParameters() 70 | { 71 | Params.push_back(std::make_shared()); 72 | return Params.back().get(); 73 | } 74 | 75 | __declspec(noinline) void DeleteParameters(NvParameter* param) 76 | { 77 | auto it = std::find_if(Params.begin(), Params.end(), 78 | [param](const auto& p) { return p.get() == param; }); 79 | Params.erase(it); 80 | } 81 | 82 | static std::shared_ptr instance() 83 | { 84 | static std::shared_ptr INSTANCE { std::make_shared() }; 85 | return INSTANCE; 86 | } 87 | }; 88 | -------------------------------------------------------------------------------- /CyberFSR/Util.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Config.h" 3 | #include "Util.h" 4 | 5 | namespace fs = std::filesystem; 6 | 7 | extern HMODULE dllModule; 8 | 9 | fs::path Util::DllPath() 10 | { 11 | static fs::path dll; 12 | if (dll.empty()) 13 | { 14 | wchar_t dllPath[MAX_PATH]; 15 | GetModuleFileNameW(dllModule, dllPath, MAX_PATH); 16 | dll = fs::path(dllPath); 17 | } 18 | return dll; 19 | } 20 | 21 | fs::path Util::ExePath() 22 | { 23 | static fs::path exe; 24 | if (exe.empty()) 25 | { 26 | wchar_t exePath[MAX_PATH]; 27 | GetModuleFileNameW(nullptr, exePath, MAX_PATH); 28 | exe = fs::path(exePath); 29 | } 30 | return exe; 31 | } 32 | 33 | double Util::MillisecondsNow() 34 | { 35 | static LARGE_INTEGER s_frequency; 36 | static BOOL s_use_qpc = QueryPerformanceFrequency(&s_frequency); 37 | double milliseconds = 0; 38 | 39 | if (s_use_qpc) 40 | { 41 | LARGE_INTEGER now; 42 | QueryPerformanceCounter(&now); 43 | milliseconds = double(1000.0 * now.QuadPart) / s_frequency.QuadPart; 44 | } 45 | else 46 | { 47 | milliseconds = double(GetTickCount()); 48 | } 49 | 50 | return milliseconds; 51 | } 52 | 53 | float Util::ConvertSharpness(float sharpness, std::optional range) 54 | { 55 | if (range == SharpnessRangeModifier::Extended) 56 | { 57 | // normalize sharpness value to [0, 1] range 58 | // originally in range [-0.99, 1] 59 | if (sharpness >= 1.0f) 60 | { 61 | return 1.0f; 62 | } 63 | else if (sharpness <= -1.0f) 64 | { 65 | return 0; 66 | } 67 | else 68 | { 69 | return (sharpness + 0.99f) / 2.0f; 70 | } 71 | } 72 | else 73 | { 74 | return sharpness; 75 | } 76 | } 77 | 78 | Util::NvParameter Util::NvParameterToEnum(const char* name) 79 | { 80 | static ankerl::unordered_dense::map NvParamTranslation = { 81 | {"SuperSampling.ScaleFactor", NvParameter::SuperSampling_ScaleFactor}, 82 | {"SuperSampling.Available", NvParameter::SuperSampling_Available}, 83 | {"SuperSampling.MinDriverVersionMajor", NvParameter::SuperSampling_MinDriverVersionMajor}, 84 | {"SuperSampling.MinDriverVersionMinor", NvParameter::SuperSampling_MinDriverVersionMinor}, 85 | {"SuperSampling.FeatureInitResult", NvParameter::SuperSampling_FeatureInitResult}, 86 | {"SuperSampling.NeedsUpdatedDriver", NvParameter::SuperSampling_NeedsUpdatedDriver}, 87 | {"#\x01", NvParameter::SuperSampling_Available}, 88 | 89 | {"Width", NvParameter::Width}, 90 | {"Height", NvParameter::Height}, 91 | {"PerfQualityValue", NvParameter::PerfQualityValue}, 92 | {"RTXValue", NvParameter::RTXValue}, 93 | {"NVSDK_NGX_Parameter_FreeMemOnReleaseFeature", NvParameter::FreeMemOnReleaseFeature}, 94 | 95 | {"OutWidth", NvParameter::OutWidth}, 96 | {"OutHeight", NvParameter::OutHeight}, 97 | 98 | {"DLSS.Render.Subrect.Dimensions.Width", NvParameter::DLSS_Render_Subrect_Dimensions_Width}, 99 | {"DLSS.Render.Subrect.Dimensions.Height", NvParameter::DLSS_Render_Subrect_Dimensions_Height}, 100 | {"DLSS.Get.Dynamic.Max.Render.Width", NvParameter::DLSS_Get_Dynamic_Max_Render_Width}, 101 | {"DLSS.Get.Dynamic.Max.Render.Height", NvParameter::DLSS_Get_Dynamic_Max_Render_Height}, 102 | {"DLSS.Get.Dynamic.Min.Render.Width", NvParameter::DLSS_Get_Dynamic_Min_Render_Width}, 103 | {"DLSS.Get.Dynamic.Min.Render.Height", NvParameter::DLSS_Get_Dynamic_Min_Render_Height}, 104 | {"Sharpness", NvParameter::Sharpness}, 105 | 106 | {"DLSSOptimalSettingsCallback", NvParameter::DLSSOptimalSettingsCallback}, 107 | {"DLSSGetStatsCallback", NvParameter::DLSSGetStatsCallback}, 108 | 109 | {"CreationNodeMask", NvParameter::CreationNodeMask}, 110 | {"VisibilityNodeMask", NvParameter::VisibilityNodeMask}, 111 | {"DLSS.Feature.Create.Flags", NvParameter::DLSS_Feature_Create_Flags}, 112 | {"DLSS.Enable.Output.Subrects", NvParameter::DLSS_Enable_Output_Subrects}, 113 | 114 | {"Color", NvParameter::Color}, 115 | {"MotionVectors", NvParameter::MotionVectors}, 116 | {"Depth", NvParameter::Depth}, 117 | {"Output", NvParameter::Output}, 118 | {"TransparencyMask", NvParameter::TransparencyMask}, 119 | {"ExposureTexture", NvParameter::ExposureTexture}, 120 | {"DLSS.Input.Bias.Current.Color.Mask", NvParameter::DLSS_Input_Bias_Current_Color_Mask}, 121 | 122 | {"DLSS.Pre.Exposure", NvParameter::Pre_Exposure}, 123 | {"DLSS.Exposure.Scale", NvParameter::Exposure_Scale}, 124 | 125 | {"Reset", NvParameter::Reset}, 126 | {"MV.Scale.X", NvParameter::MV_Scale_X}, 127 | {"MV.Scale.Y", NvParameter::MV_Scale_Y}, 128 | {"Jitter.Offset.X", NvParameter::Jitter_Offset_X}, 129 | {"Jitter.Offset.Y", NvParameter::Jitter_Offset_Y}, 130 | 131 | {"SizeInBytes", NvParameter::SizeInBytes}, 132 | {"Snippet.OptLevel", NvParameter::OptLevel}, 133 | {"#\x44", NvParameter::OptLevel}, 134 | {"Snippet.IsDevBranch", NvParameter::IsDevSnippetBranch}, 135 | {"#\x45", NvParameter::IsDevSnippetBranch} 136 | }; 137 | 138 | return NvParamTranslation[std::string(name)]; 139 | } 140 | -------------------------------------------------------------------------------- /CyberFSR/Util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Config.h" 3 | 4 | namespace Util 5 | { 6 | std::filesystem::path ExePath(); 7 | 8 | std::filesystem::path DllPath(); 9 | 10 | double MillisecondsNow(); 11 | 12 | float ConvertSharpness(float sharpness, std::optional range); 13 | 14 | enum class NvParameter 15 | { 16 | Invalid, 17 | 18 | //SuperSampling 19 | SuperSampling_ScaleFactor, 20 | SuperSampling_Available, 21 | SuperSampling_MinDriverVersionMajor, 22 | SuperSampling_MinDriverVersionMinor, 23 | SuperSampling_FeatureInitResult, 24 | SuperSampling_NeedsUpdatedDriver, 25 | //User settings stuff 26 | Width, 27 | Height, 28 | PerfQualityValue, 29 | RTXValue, 30 | FreeMemOnReleaseFeature, 31 | //Resolution stuff 32 | OutWidth, 33 | OutHeight, 34 | 35 | DLSS_Render_Subrect_Dimensions_Width, 36 | DLSS_Render_Subrect_Dimensions_Height, 37 | DLSS_Get_Dynamic_Max_Render_Width, 38 | DLSS_Get_Dynamic_Max_Render_Height, 39 | DLSS_Get_Dynamic_Min_Render_Width, 40 | DLSS_Get_Dynamic_Min_Render_Height, 41 | Sharpness, 42 | //Callbacks 43 | DLSSGetStatsCallback, 44 | DLSSOptimalSettingsCallback, 45 | 46 | //Render stuff 47 | CreationNodeMask, 48 | VisibilityNodeMask, 49 | DLSS_Feature_Create_Flags, 50 | DLSS_Enable_Output_Subrects, 51 | 52 | //D3D12 Buffers 53 | Color, 54 | MotionVectors, 55 | Depth, 56 | Output, 57 | TransparencyMask, 58 | ExposureTexture, 59 | DLSS_Input_Bias_Current_Color_Mask, 60 | Pre_Exposure, 61 | Exposure_Scale, 62 | 63 | Reset, 64 | MV_Scale_X, 65 | MV_Scale_Y, 66 | Jitter_Offset_X, 67 | Jitter_Offset_Y, 68 | 69 | //Dev Stuff 70 | SizeInBytes, 71 | OptLevel, 72 | IsDevSnippetBranch 73 | }; 74 | 75 | NvParameter NvParameterToEnum(const char* name); 76 | }; 77 | 78 | inline void ThrowIfFailed(HRESULT hr) 79 | { 80 | if (FAILED(hr)) 81 | { 82 | // Set a breakpoint on this line to catch DirectX API errors 83 | throw std::exception(); 84 | } 85 | } -------------------------------------------------------------------------------- /CyberFSR/ViewMatrixHook.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "ViewMatrixHook.h" 3 | #include "scanner.h" 4 | std::unique_ptr ViewMatrixHook::Create(const Config& config) 5 | { 6 | switch (config.Method.value_or(ViewMethod::Config)) 7 | { 8 | case ViewMethod::Cyberpunk2077: 9 | return std::make_unique(); 10 | 11 | case ViewMethod::RDR2: 12 | return std::make_unique(); 13 | case ViewMethod::DL2: 14 | return std::make_unique(); 15 | 16 | case ViewMethod::Config: 17 | default: 18 | return std::make_unique( 19 | config.VerticalFOV.value_or(60.0f), 20 | config.FarPlane.value_or(std::numeric_limits::infinity()), 21 | config.NearPlane.value_or(0.0f) 22 | ); 23 | } 24 | } 25 | 26 | #pragma region Configured 27 | 28 | ViewMatrixHook::Configured::Configured(float fov, float nearPlane, float farPlane) 29 | : Fov(fov) 30 | , NearPlane(nearPlane) 31 | , FarPlane(farPlane) 32 | { 33 | } 34 | 35 | float ViewMatrixHook::Configured::GetFov() 36 | { 37 | return Fov; 38 | } 39 | 40 | float ViewMatrixHook::Configured::GetFarPlane() 41 | { 42 | return FarPlane; 43 | } 44 | 45 | float ViewMatrixHook::Configured::GetNearPlane() 46 | { 47 | return NearPlane; 48 | } 49 | 50 | #pragma endregion 51 | 52 | #pragma region Cyberpunk2077 53 | 54 | ViewMatrixHook::Cyberpunk2077::Cyberpunk2077() 55 | { 56 | //TODO check for different executable versions 57 | 58 | /* 59 | Protip for future self to get the offsets, search for the vertical FOV to get the structure, then look for references to that structure and afterwards look for static references 60 | */ 61 | 62 | auto loc = *(uintptr_t*)scanner::GetOffsetFromInstruction(L"Cyberpunk2077.exe", "F3 0F 7F 0D ? ? ? ? E8", 4); 63 | camParams = ((CameraParams*)(loc + 0x60)); 64 | } 65 | 66 | float ViewMatrixHook::Cyberpunk2077::GetFov() 67 | { 68 | return camParams->Fov; 69 | } 70 | 71 | float ViewMatrixHook::Cyberpunk2077::GetFarPlane() 72 | { 73 | return camParams->FarPlane; 74 | } 75 | 76 | float ViewMatrixHook::Cyberpunk2077::GetNearPlane() 77 | { 78 | return camParams->NearPlane; 79 | } 80 | 81 | #pragma endregion 82 | 83 | #pragma region RDR2 84 | 85 | ViewMatrixHook::RDR2::RDR2() 86 | { 87 | auto loc = scanner::GetOffsetFromInstruction(L"RDR2.exe", "4C 8D 2D ? ? ? ? 48 85 DB", 3); 88 | camParams = ((CameraParams*)(loc + 0x60)); 89 | } 90 | 91 | float ViewMatrixHook::RDR2::GetFov() 92 | { 93 | return camParams->Fov; 94 | } 95 | 96 | float ViewMatrixHook::RDR2::GetFarPlane() 97 | { 98 | return camParams->FarPlane; 99 | } 100 | 101 | float ViewMatrixHook::RDR2::GetNearPlane() 102 | { 103 | return camParams->NearPlane; 104 | } 105 | 106 | #pragma endregion 107 | 108 | #pragma region DL2 109 | 110 | ViewMatrixHook::DL2::DL2() 111 | { 112 | // the real fov value is found in "gamedll_ph_x64_rwdi.dll" but a some pointers from "engine_x64_rwdi.dll" has access to it 113 | // in DL2 the CameraDefaultFOV is 57 114 | // the game keeps 57 fov as default and there is another fov value called extraFOV which users can change as part of game settings 115 | // the real fov is CameraDefaultFOV + extraFOV 116 | // the address below is the real FOV address but it is not accessible until the load into the game world so we find the CameraDefaultFOV and extraFOV address and calculate our fov from these 117 | // auto loc = (*(uintptr_t*)(*(uintptr_t*)(*(uintptr_t*)(*(uintptr_t*)(*(uintptr_t*)(scanner::GetOffsetFromInstruction(L"engine_x64_rwdi.dll", "48 8D 2D ? ? ? ? 8B 0D", 3) + 0x18) + 0x28) + 0x20) + 0x18) + 0x150) + 0x98); 118 | uintptr_t ptr = (scanner::GetOffsetFromInstruction(L"gamedll_ph_x64_rwdi.dll","EB ? E8 ? ? ? ? 48 8D 78 ? E8", 3) + 0xDF); 119 | ptr += (*(int32_t*)ptr + sizeof(int32_t)) + 0xCC8; // ptr + 0xCC8 this is pointer to whatever is saved in CameraDefaultFOV from player_variables.scr 120 | camParams = (CameraParams*)ptr; 121 | 122 | auto ptr2 = (*(uintptr_t*)(*(uintptr_t*)scanner::GetOffsetFromInstruction(L"engine_x64_rwdi.dll", "48 8B 05 ? ? ? ? 8B DA", 3)+0xE0)+0x15C); 123 | extracamParams = (ExtraCameraParams*)ptr2; //extraFOV 124 | } 125 | 126 | float ViewMatrixHook::DL2::GetFov() 127 | { 128 | auto param1 = camParams->Fov; 129 | auto param2 = extracamParams->Fov; 130 | 131 | return (param1 + param2); 132 | } 133 | 134 | float ViewMatrixHook::DL2::GetFarPlane() 135 | { 136 | return camParams->FarPlane; 137 | } 138 | 139 | float ViewMatrixHook::DL2::GetNearPlane() 140 | { 141 | return camParams->NearPlane; 142 | } 143 | 144 | #pragma endregion 145 | -------------------------------------------------------------------------------- /CyberFSR/ViewMatrixHook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Config.h" 3 | 4 | class ViewMatrixHook 5 | { 6 | public: 7 | virtual float GetFov() = 0; 8 | virtual float GetFarPlane() = 0; 9 | virtual float GetNearPlane() = 0; 10 | 11 | class Configured; 12 | class Cyberpunk2077; 13 | class RDR2; 14 | class DL2; 15 | 16 | static std::unique_ptr Create(const Config& config); 17 | }; 18 | 19 | class ViewMatrixHook::Configured : public ViewMatrixHook 20 | { 21 | public: 22 | Configured(float fov, float nearPlane, float farPlane); 23 | 24 | float GetFov(); 25 | float GetFarPlane(); 26 | float GetNearPlane(); 27 | 28 | private: 29 | float Fov; 30 | float FarPlane; 31 | float NearPlane; 32 | }; 33 | 34 | class ViewMatrixHook::Cyberpunk2077 : public ViewMatrixHook 35 | { 36 | public: 37 | Cyberpunk2077(); 38 | 39 | float GetFov(); 40 | float GetFarPlane(); 41 | float GetNearPlane(); 42 | 43 | private: 44 | struct CameraParams 45 | { 46 | unsigned char unknown0[0x20]; 47 | float Fov; 48 | unsigned char unknown1[0x1C]; 49 | float NearPlane; 50 | float FarPlane; 51 | }; 52 | 53 | CameraParams* camParams = nullptr; 54 | }; 55 | 56 | class ViewMatrixHook::RDR2 : public ViewMatrixHook 57 | { 58 | public: 59 | RDR2(); 60 | 61 | float GetFov(); 62 | float GetFarPlane(); 63 | float GetNearPlane(); 64 | 65 | private: 66 | struct CameraParams 67 | { 68 | float Fov; 69 | float NearPlane; 70 | float FarPlane; 71 | }; 72 | 73 | CameraParams* camParams = nullptr; 74 | }; 75 | 76 | class ViewMatrixHook::DL2 : public ViewMatrixHook 77 | { 78 | public: 79 | DL2(); 80 | 81 | float GetFov(); 82 | float GetFarPlane(); 83 | float GetNearPlane(); 84 | 85 | private: 86 | struct ExtraCameraParams 87 | { 88 | float Fov; 89 | }; 90 | 91 | ExtraCameraParams* extracamParams = nullptr; 92 | 93 | struct CameraParams 94 | { 95 | float Fov; 96 | float NearPlane; 97 | float FarPlane; 98 | }; 99 | 100 | CameraParams* camParams = nullptr; 101 | }; -------------------------------------------------------------------------------- /CyberFSR/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | HMODULE dllModule; 4 | 5 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 6 | { 7 | switch (ul_reason_for_call) 8 | { 9 | case DLL_PROCESS_ATTACH: 10 | DisableThreadLibraryCalls(hModule); 11 | dllModule = hModule; 12 | break; 13 | case DLL_THREAD_ATTACH: 14 | break; 15 | case DLL_THREAD_DETACH: 16 | break; 17 | case DLL_PROCESS_DETACH: 18 | break; 19 | } 20 | return TRUE; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /CyberFSR/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #define NOMINMAX 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #define NV_WINDOWS 26 | #define NVSDK_NGX 27 | #define NGX_ENABLE_DEPRECATED_GET_PARAMETERS 28 | #include 29 | #include 30 | 31 | #include "..\external\unordered_dense\include\ankerl\unordered_dense.h" 32 | #include "SimpleIni.h" -------------------------------------------------------------------------------- /CyberFSR/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" -------------------------------------------------------------------------------- /CyberFSR/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "framework.h" -------------------------------------------------------------------------------- /CyberFSR/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by CyberFSR.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /CyberFSR/scanner.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "scanner.h" 3 | 4 | std::pair GetModule(const std::wstring_view moduleName) 5 | { 6 | const static uintptr_t moduleBase = reinterpret_cast(GetModuleHandleW(moduleName.data())); 7 | const static uintptr_t moduleEnd = [&]() 8 | { 9 | auto ntHeaders = reinterpret_cast(moduleBase + reinterpret_cast(moduleBase)->e_lfanew); 10 | return static_cast(moduleBase + ntHeaders->OptionalHeader.SizeOfImage); 11 | }(); 12 | 13 | return { moduleBase, moduleEnd }; 14 | } 15 | 16 | 17 | uintptr_t FindPattern(uintptr_t startAddress, uintptr_t maxSize, const char* mask) 18 | { 19 | std::vector> pattern; 20 | 21 | for (size_t i = 0; i < strlen(mask);) 22 | { 23 | if (mask[i] != '?') 24 | { 25 | pattern.emplace_back(static_cast(strtoul(&mask[i], nullptr, 16)), false); 26 | i += 3; 27 | } 28 | else 29 | { 30 | pattern.emplace_back(0x00, true); 31 | i += 2; 32 | } 33 | } 34 | 35 | const auto dataStart = reinterpret_cast(startAddress); 36 | const auto dataEnd = dataStart + maxSize + 1; 37 | 38 | auto sig = std::search(dataStart, dataEnd, pattern.begin(), pattern.end(), 39 | [](uint8_t currentByte, std::pair Pattern) 40 | { 41 | return Pattern.second || (currentByte == Pattern.first); 42 | }); 43 | 44 | if (sig == dataEnd) 45 | return NULL; 46 | 47 | return std::distance(dataStart, sig) + startAddress; 48 | } 49 | 50 | uintptr_t scanner::GetAddress(const std::wstring_view moduleName, const std::string_view pattern, ptrdiff_t offset) 51 | { 52 | uintptr_t address = FindPattern(GetModule(moduleName.data()).first, GetModule(moduleName.data()).second - GetModule(moduleName.data()).first, pattern.data()); 53 | 54 | if ((GetModuleHandleW(moduleName.data()) != nullptr) && (address != NULL)) 55 | { 56 | return (address + offset); 57 | } 58 | else 59 | { 60 | throw std::runtime_error("Pattern not found!"); 61 | } 62 | } 63 | 64 | uintptr_t scanner::GetOffsetFromInstruction(const std::wstring_view moduleName, const std::string_view pattern, ptrdiff_t offset) 65 | { 66 | uintptr_t address = FindPattern(GetModule(moduleName.data()).first, GetModule(moduleName.data()).second - GetModule(moduleName.data()).first, pattern.data()); 67 | 68 | if ((GetModuleHandleW(moduleName.data()) != nullptr) && (address != NULL)) 69 | { 70 | auto reloffset = *reinterpret_cast(address + offset) + sizeof(int32_t); 71 | return (address + offset + reloffset); 72 | } 73 | else 74 | { 75 | throw std::runtime_error("Pattern not found!"); 76 | } 77 | } -------------------------------------------------------------------------------- /CyberFSR/scanner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "framework.h" 4 | 5 | 6 | namespace scanner 7 | { 8 | uintptr_t GetAddress(const std::wstring_view moduleName, const std::string_view pattern, ptrdiff_t offset = 0); 9 | uintptr_t GetOffsetFromInstruction(const std::wstring_view moduleName, const std::string_view pattern, ptrdiff_t offset = 0); 10 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 PotatoOfDoom 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DLSS2FSR (CyberFSR/PotatoFSR) 2 | Replacing DLSS 2.x with FSR 2.1.2 for various games such as Cyberpunk 2077, Red Dead Redemption 2, etc. 3 | 4 | It includes a DLL wrapper/injector (winmm.dll) to disable Nvidia GeForce RTX GPU checking, so AMD Radeon / Nvidia GTX users can enjoy the mod. 5 | 6 | ## Join our Cult here: https://discord.gg/2JDHx6kcXB 7 | 8 | 9 | ## List of Supported Games 10 | * A Plague Tale Requiem (https://www.nexusmods.com/aplaguetalerequiem/mods/9) 11 | * Amid Evil (https://steamcommunity.com/app/673130/discussions/0/4960174866676781850) 12 | * Amok Runner 13 | * Aron's Adventure 14 | * Assetto Corsa Competizione 15 | * Batora - Lost Haven 16 | * BLACKTAIL 17 | * Blind Fate: Edo no Yami 18 | * Bright Memory: Infinite (https://www.nexusmods.com/brightmemoryinfinite/mods/4) 19 | * Dakar Desert Rally 20 | * DOOM Eternal (https://www.nexusmods.com/doometernal/mods/1170) 21 | * Deep Rock Galactic 22 | * Deliver Us the Moon 23 | * Diablo II - Resurrected (https://www.nexusmods.com/diablo2resurrected/mods/269) 24 | * Dream Cycle 25 | * Evil West 26 | * F.I.S.T. - Forged In Shadow Torch (https://www.nexusmods.com/fistforgedinshadowtorch/mods/2) 27 | * Fobia - St.Dinfna Hotel 28 | * Frozen Flame 29 | * GTA Liberty City Definitive Edition 30 | * GTA San Andreas Definitive Edition 31 | * GTA Vice City Definitive Edition 32 | * Ghostrunner (https://www.nexusmods.com/ghostrunner/mods/17) 33 | * Gotham Knights 34 | * Gungrave G.O.R.E 35 | * Hell Pie 36 | * Hello Neighbor 2 37 | * Horizon Zero Dawn (https://www.nexusmods.com/horizonzerodawn/mods/133) 38 | * Hot Wheels Unleashed 39 | * Hydroneer 40 | * ICARUS 41 | * INDUSTRIA 42 | * Into the Radius VR 43 | * Kena: Bridge of Spirits (https://www.nexusmods.com/kenabridgeofspirits/mods/18) 44 | * Land of the Vikings 45 | * Marvel's Spider-Man Remastered (https://www.nexusmods.com/marvelsspidermanremastered/mods/683) 46 | * Marvel's Spider-Man Miles Morales (https://www.nexusmods.com/spidermanmilesmorales/mods/33) 47 | * Minecraft Bedrock 1.19.40.2 (and up) 48 | * Myst (https://www.nexusmods.com/myst/mods/3) 49 | * Necromunda: Hired Gun (https://www.nexusmods.com/necromundahiredgun/mods/8) 50 | * No Man's Sky (https://www.nexusmods.com/nomanssky/mods/2485) 51 | * Ready or Not (https://www.nexusmods.com/readyornot/mods/1953) 52 | * Red Dead Redemption 2 (https://www.nexusmods.com/reddeadredemption2/mods/1640) 53 | * Rise of the Tomb Raider (https://www.nexusmods.com/riseofthetombraider/mods/82) 54 | * Severed Steel 55 | * Soulstice (https://www.nexusmods.com/soulstice/mods/3) 56 | * Succubus 57 | * Sword and Fairy 7 58 | * The Ascent (https://www.nexusmods.com/theascent/mods/11) 59 | * The Chant 60 | * The Last Oricru 61 | * The Orville - Interactive Fan Experience 62 | * WRC Generations – The FIA WRC Official Game 63 | 64 | 65 | ## Installation 66 | ### Windows 67 | * Download the latest relase from [Release Page](https://github.com/MOVZX/CyberFSR2/releases) 68 | * Extract the contents of the archive next to the game EXE file in your games folder 69 | * Make sure the game is running in DX12 mode: 70 | ![Steam setting](https://i.imgur.com/a8Sybru.png) 71 | * That's it. Now DLSS option should appear in settigs 72 | 73 | ### GNU/Linux 74 | * Download the latest relase from [Release Page](https://github.com/MOVZX/CyberFSR2/releases) 75 | * Extract the contents of the archive next to the game EXE file in your games folder 76 | * Set game launch options (Steam) to: `WINEDLLOVERRIDES="winmm=n,b" %command%` 77 | * Or if you're using Lutris/Heroic/etc you can set it like this: 78 | ![WINE setting](https://i.imgur.com/v7JLSUY.png) 79 | * Make sure the game is running in DX12 mode: 80 | ![Steam setting](https://i.imgur.com/a8Sybru.png) 81 | * That's it. Now DLSS option should appear in settigs 82 | 83 | 84 | ## Tweaks 85 | ### UE4 Ghosting/Flickering Fixes 86 | 87 | Edit **Engine.ini** file located in ```%LOCALAPPDATA%\GAMENAME\Saved\Config\WindowsNoEditor\Engine.ini``` and paste the tweaks below to the very bottom of the line: 88 | ``` 89 | [SystemSettings] 90 | r.NGX.DLSS.DilateMotionVectors=0 91 | r.SceneColorFormat=5 92 | ``` 93 | #### Location for each games is different, but here are some locations for the games supported by this Mod: 94 | 95 | - **Amid Evil**: ```%LOCALAPPDATA%\AmidEvil\Saved\Config\WindowsNoEditor\Engine.ini``` 96 | - **Amok Runner**: ```%LOCALAPPDATA%\Amok\Saved\Config\WindowsNoEditor\Engine.ini``` 97 | - **Assetto Corsa Competizione**: ```%LOCALAPPDATA%\AC2\Saved\Config\WindowsNoEditor\Engine.ini``` 98 | - **Aron's Adventure**: ```%LOCALAPPDATA%\AronsAdventure\Saved\Config\WindowsNoEditor\Engine.ini``` 99 | - **Batora - Lost Haven**: ```%LOCALAPPDATA%\Batora\Saved\Config\WindowsNoEditor\Engine.ini``` 100 | - **BLACKTAIL**: ```%LOCALAPPDATA%\BLACKTAIL\Saved\Config\WindowsNoEditor\Engine.ini``` 101 | - **Blind Fate: Edo no Yami**: ```%LOCALAPPDATA%\Yami\Saved\Config\WindowsNoEditor\Engine.ini``` 102 | - **Bright Memory: Infinite**: ```%LOCALAPPDATA%\BrightMemoryInfinite\Saved\Config\WindowsNoEditor\Engine.ini``` 103 | - **Dakar Desert Rally**: ```%LOCALAPPDATA%\Dakar2Game\Saved\Config\WindowsNoEditor\Engine.ini``` 104 | - **Deep Rock Galactic**: ```GAME_INSTALL_LOCATION\Deep Rock Galactic\FSD\Saved\Config\WindowsNoEditor\Engine.ini``` 105 | - **Deliver Us the Moon**: ```%LOCALAPPDATA%\MoonMan\Saved\Config\WindowsNoEditor\Engine.ini``` 106 | - **Dream Cycle**: ```%LOCALAPPDATA%\DreamCycle\Saved\Config\WindowsNoEditor\Engine.ini``` 107 | - **F.I.S.T. - Forged In Shadow Torch**: ```%LOCALAPPDATA%\ZingangGame\Saved\Config\WindowsNoEditor\Engine.ini``` 108 | - **Fobia - St.Dinfna Hotel**: ```%LOCALAPPDATA%\Fobia\Saved\Config\WindowsNoEditor\Engine.ini``` 109 | - **Frozen Flame**: ```%LOCALAPPDATA%\FrozenFlame\Saved\Config\WindowsNoEditor\Engine.ini``` 110 | - **Ghostrunner**: ```%LOCALAPPDATA%\Ghostrunner\Saved\Config\WindowsNoEditor\Engine.ini``` 111 | - **Gotham Knights**: ```%LOCALAPPDATA%\Mercury\Saved\Config\WindowsNoEditor\Engine.ini``` 112 | - **Gungrave G.O.R.E**: ```%LOCALAPPDATA%\GunGraveGore\Saved\WindowsNoEditor\Engine.ini``` 113 | - **Hell Pie**: ```%LOCALAPPDATA%\HellPie\Saved\Config\WindowsNoEditor\Engine.ini``` 114 | - **Hello Neighbor 2**: ```%LOCALAPPDATA%\HelloNeighbor2\Saved\Config\WindowsNoEditor\Engine.ini``` 115 | - **Hot Wheels Unleashed**: ```%LOCALAPPDATA%\hotwheels\Saved\Config\WindowsNoEditor\Engine.ini``` 116 | - **Hydroneer**: ```%LOCALAPPDATA%\Mining\Saved\Config\WindowsNoEditor\Engine.ini``` 117 | - **ICARUS**: ```%LOCALAPPDATA%\Icarus\Saved\Config\WindowsNoEditor\Engine.ini``` 118 | - **INDUSTRIA**: ```%LOCALAPPDATA%\Industria\Saved\Config\WindowsNoEditor\Engine.ini``` 119 | - **Into the Radius VR**: ```%LOCALAPPDATA%\IntoTheRadius\Saved\Config\WindowsNoEditor\Engine.ini``` 120 | - **Kena: Bridge of Spirits**: ```%LOCALAPPDATA%\Kena\Saved\Config\WindowsNoEditor\Engine.ini``` 121 | - **Land of the Vikings**: ```%LOCALAPPDATA%\VikingOyunu\Saved\Config\WindowsNoEditor\Engine.ini``` 122 | - **Myst**: ```%LOCALAPPDATA%\Myst\Saved\Config\WindowsNoEditor\Engine.ini``` 123 | - **Necromunda: Hired Gun**: ```%LOCALAPPDATA%\Streumon\Necromunda\Saved\Config\WindowsNoEditor\Engine.ini``` 124 | - **Ready or Not**: ```%LOCALAPPDATA%\ReadyOrNot\Saved\Config\WindowsNoEditor\Engine.ini``` 125 | - **Severed Steel**: ```%LOCALAPPDATA%\ThankYouVeryCool\Saved\Config\WindowsNoEditor\Engine.ini``` 126 | - **Soulstice**: ```GAME_INSTALL_LOCATION\Soulstice\Saved\Config\WindowsNoEditor\Engine.ini``` 127 | - **Succubus**: ```%LOCALAPPDATA%\Succubus\Saved\Config\WindowsNoEditor\Engine.ini``` 128 | - **Sword and Fairy 7**: ```%LOCALAPPDATA%\Pal7\Saved\Config\WindowsNoEditor\Engine.ini``` 129 | - **The Ascent**: ```%LOCALAPPDATA%\TheAscent\Saved\Config\WindowsNoEditor\Engine.ini``` 130 | - **The Chant**: ```%LOCALAPPDATA%\Chant\Saved\Config\WindowsNoEditor\Engine.ini``` 131 | - **The Last Oricru**: ```%LOCALAPPDATA%\LostHero\Saved\Config\WindowsNoEditor\Engine.ini``` 132 | - **The Orville - Interactive Fan Experience**: ```GAME_INSTALL_LOCATION\OrvilleFanGame\Saved\Config\WindowsNoEditor\Engine.ini``` 133 | 134 | 135 | ## Uninstallation 136 | * Delete nvngx.dll, nvngx.ini, and winmm.dll 137 | * GNU/Linux users should refer to prior command 138 | -------------------------------------------------------------------------------- /linuxinstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cp -r * ../ 3 | 4 | cd ../ 5 | cp -r bin/x64/* . 6 | DIR="$(pwd)" 7 | echo $DIR 8 | steam() { 9 | echo $DIR 10 | b=${DIR%/steamapps*} 11 | b=$b/steamapps/compatdata/1091500/pfx/ 12 | echo " " 13 | echo " " 14 | 15 | echo "I am going to run this command, are you sure?" 16 | echo "WINEPREFIX=$b /bin/wine64 regedit EnableSignatureOverride.reg" 17 | read -p "Press [Enter] to continue..." 18 | WINEPREFIX=$b /bin/wine64 regedit EnableSignatureOverride.reg 19 | } 20 | 21 | heroic(){ 22 | home=$(echo ~) 23 | home=$home/Games/Heroic/Prefixes/cyberpunk-2077 24 | echo "I am going to run this command, are you sure?" 25 | echo "WINEPREFIX=$home /bin/wine64 regedit EnableSignatureOverride.reg" 26 | read -p "Press [Enter] to continue..." 27 | WINEPREFIX=$home /bin/wine64 regedit EnableSignatureOverride.reg 28 | 29 | } 30 | 31 | gog(){ 32 | home=$(echo ~) 33 | home=$home/Games/cyberpunk-2077 34 | echo "I am going to run this command, are you sure?" 35 | echo "WINEPREFIX=$home /bin/wine64 regedit EnableSignatureOverride.reg" 36 | read -p "Press [Enter] to continue..." 37 | WINEPREFIX=$home /bin/wine64 regedit EnableSignatureOverride.reg 38 | 39 | } 40 | if [ -f "$DIR/Cyberpunk2077.exe" ]; then 41 | echo "what launcher are you using?" 42 | echo "1. Steam" 43 | echo "2. Gog (lutris)" 44 | echo "3. Heroic (epic games, it probably also works for gog tho) " 45 | read -p "Enter your choice: " choice 46 | case $choice in 47 | 1) 48 | steam 49 | ;; 50 | 2) 51 | gog 52 | ;; 53 | 3) 54 | heroic 55 | ;; 56 | *) 57 | echo "Invalid choice" 58 | ;; 59 | esac 60 | else 61 | echo "Cyberpunk2077.exe not found, please extract the files in the directory where Cyberpunk2077.exe is stored and try again" 62 | exit 1 63 | fi 64 | 65 | -------------------------------------------------------------------------------- /nvngx.ini: -------------------------------------------------------------------------------- 1 | ; All settings can be set to auto to have the mod automatically control the values 2 | 3 | [Depth] 4 | ; auto, true or false 5 | DepthInverted=auto 6 | 7 | [Color] 8 | ; auto, true or false 9 | AutoExposure=auto 10 | ; auto, true or false 11 | HDR=auto 12 | 13 | [MotionVectors] 14 | ; auto, true or false 15 | JitterCancellation=auto 16 | ; auto, true or false 17 | DisplayResolution=auto 18 | 19 | [Sharpening] 20 | ; auto, true or false 21 | EnableSharpening=auto 22 | ; auto, or number between 0 and 1.0 23 | Sharpness=auto 24 | ; normal or extended 25 | SharpnessRange=auto 26 | 27 | [UpscaleRatio] 28 | ; set this to true to enable the internal resolution override 29 | UpscaleRatioOverrideEnabled=auto 30 | ; 31 | ; set the forced upscale ratio value 32 | ; 33 | ; resolution values are calculated in this way: 34 | ; OutHeight = Height / ratio; 35 | ; OutWidth = Width / ratio; 36 | ; example ratios: Quality preset = 1.5; Ultra performance preset = 3.0 37 | UpscaleRatioOverrideValue=auto 38 | 39 | [QualityOverrides] 40 | ; Set custom upscaling ratio for each quality mode 41 | ; 42 | ; Set this to true to enable custom quality mode overrides 43 | QualityRatioOverrideEnabled=auto 44 | ; 45 | ; Default values: 46 | ; Ultra Quality : 1.3 47 | ; Quality : 1.5 48 | ; Balanced : 1.7 49 | ; Performance : 2.0 50 | ; Ultra Performance : 3.0 51 | ; 52 | QualityRatioUltraQuality=1.3 53 | QualityRatioQuality=1.5 54 | QualityRatioBalanced=1.7 55 | QualityRatioPerformance=2.0 56 | QualityRatioUltraPerformance=3.0 57 | 58 | [View] 59 | ; Set this to auto, config, cyberpunk2077, rdr2 or dl2 60 | Method=auto 61 | ; 62 | ; Number for the vertical field of view value 63 | ; Use the converter below if you only know the horizontal field of view 64 | ; 65 | ; Using Python 66 | ; 67 | ; import math 68 | ; math.degrees(2*math.atan(math.tan((math.radians(horizontalFOVfromTheFOVSlider))/2)*screenHeight/screenWidth)) 69 | ; 70 | VerticalFOV=auto 71 | ; Number that is at least 0 72 | NearPlane=auto 73 | ; Number that is higher than the NearPlane value 74 | FarPlane=auto 75 | ; Set this to true if the far clip plane is infinite 76 | InfiniteFarPlane=auto 77 | 78 | [Hotfix] 79 | ; true or false 80 | DisableReactiveMask=false --------------------------------------------------------------------------------