Skip to content

Add support for installing and enabling DXVK-NVAPI #2567

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ae40ebd
initial implementation of dxvk-nvapi installation
Etaash-mathamsetty Mar 25, 2023
13fbf05
Update translation.json
Etaash-mathamsetty Mar 25, 2023
94162ae
bugfix
Etaash-mathamsetty Mar 25, 2023
ccc8a41
remove duplicate code
Etaash-mathamsetty Mar 25, 2023
4d35668
fix downloading
Etaash-mathamsetty Apr 2, 2023
02e3a76
Merge branch 'main' into dxvk-nvapi
Etaash-mathamsetty Apr 2, 2023
94ac185
experimental support to automatically copy nvngx.dll
Etaash-mathamsetty Apr 3, 2023
a4a1d84
strip binary
Etaash-mathamsetty Apr 3, 2023
bfd723b
Merge branch 'main' into dxvk-nvapi
Etaash-mathamsetty Apr 9, 2023
8ba65b1
fix issue with merged code
Etaash-mathamsetty Apr 9, 2023
f36bae4
Merge remote-tracking branch 'upstream/main' into dxvk-nvapi
Etaash-mathamsetty May 22, 2023
3f6a8e8
use neon module
Etaash-mathamsetty May 22, 2023
9cd744e
Delete nvngx_finder
Etaash-mathamsetty May 22, 2023
90ccf91
fix cargo-cp-artifact
Etaash-mathamsetty May 22, 2023
4748e20
update nvngx-finder
Etaash-mathamsetty May 22, 2023
5521dc1
update nvngx-finder again
Etaash-mathamsetty May 22, 2023
899c953
Update flatpak-build.yml
Etaash-mathamsetty May 23, 2023
d99c7c5
Update flatpak-build.yml
Etaash-mathamsetty May 23, 2023
46c9ae5
Merge remote-tracking branch 'upstream/main' into dxvk-nvapi
Etaash-mathamsetty May 23, 2023
793c1bb
Merge remote-tracking branch 'upstream/main' into dxvk-nvapi
Etaash-mathamsetty May 23, 2023
0576fe2
install cargo in flatpak CI
Etaash-mathamsetty May 23, 2023
eeb9ee6
Revert "install cargo in flatpak CI"
Etaash-mathamsetty May 23, 2023
8483959
remove nvngx-finder and use new approach
Etaash-mathamsetty May 26, 2023
1672d82
Merge branch 'main' into dxvk-nvapi
Etaash-mathamsetty Jul 19, 2023
c774f4a
Merge branch 'main' into dxvk-nvapi
Etaash-mathamsetty Jul 29, 2023
9e4f967
Merge remote-tracking branch 'upstream/main' into dxvk-nvapi
Etaash-mathamsetty Aug 7, 2023
8104886
auto install dxvk-nvapi
Etaash-mathamsetty Aug 7, 2023
aa2168c
improve toggle
Etaash-mathamsetty Aug 7, 2023
2d9c4aa
Update AutoDXVKNVAPI.tsx
Etaash-mathamsetty Aug 7, 2023
590ddea
log when nvngx.dll is not found
Etaash-mathamsetty Aug 7, 2023
a81cc88
Update AutoDXVKNVAPI.tsx
Etaash-mathamsetty Aug 7, 2023
42502bb
fix flatpak nvapi
Etaash-mathamsetty Aug 8, 2023
f14ffcd
Update index.ts
Etaash-mathamsetty Aug 8, 2023
c9cd515
Merge remote-tracking branch 'upstream/main' into dxvk-nvapi
Etaash-mathamsetty Aug 8, 2023
6c19108
Update vulkan-helper
Etaash-mathamsetty Aug 8, 2023
50d8ec3
Update flatpak-build.yml
Etaash-mathamsetty Aug 10, 2023
22c6ecc
Merge remote-tracking branch 'upstream/main' into dxvk-nvapi
Etaash-mathamsetty Aug 10, 2023
3575ae9
fix translation
Etaash-mathamsetty Aug 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified public/bin/linux/vulkan-helper
Binary file not shown.
2 changes: 2 additions & 0 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@
"disable_logs": "Toggle this checkbox ON to disable most of the writes to log files (critical information is always logged). Make sure to turn OFF this setting before reporting any issue.",
"dxvk": "DXVK is a Vulkan-based translational layer for DirectX 9, 10 and 11 games. Enabling may improve compatibility. Might cause issues especially for older DirectX games.",
"dxvkfpslimit": "Sets a frame rate cap for DXVK games",
"dxvknvapi": "DXVK-NVAPI is an implementation of NVAPI built on top of DXVK and the linux native NVAPI, it allows for the usage of DLSS on Nvidia GPUs.",
"esync": "Esync aims to reduce wineserver overhead in CPU-intensive games. Enabling may improve performance.",
"fsync": "Fsync aims to reduce wineserver overhead in CPU-intensive games. Enabling may improve performance on supported Linux kernels.",
"game_language": {
Expand Down Expand Up @@ -483,6 +484,7 @@
"alt-legendary-bin": "Choose an Alternative Legendary Binary",
"alt-nile-bin": "Choose an Alternative Nile Binary",
"autodxvk": "Auto Install/Update DXVK on Prefix",
"autodxvknvapi": "Auto Install/Update DXVK-NVAPI on Prefix",
"autosync": "Autosync Saves",
"autoUpdateGames": "Automatically update games",
"autovkd3d": "Auto Install/Update VKD3D on Prefix",
Expand Down
2 changes: 2 additions & 0 deletions src/backend/api/wine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {

export const toggleDXVK = async (args: ToolArgs) =>
ipcRenderer.invoke('toggleDXVK', args)
export const toggleDXVKNVAPI = async (args: ToolArgs) =>
ipcRenderer.invoke('toggleDXVKNVAPI', args)
export const toggleVKD3D = (args: ToolArgs) =>
ipcRenderer.send('toggleVKD3D', args)
export const isFlatpak = async (): Promise<boolean> =>
Expand Down
1 change: 1 addition & 0 deletions src/backend/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ class GlobalConfigV0 extends GlobalConfig {
addStartMenuShortcuts: false,
autoInstallDxvk: true,
autoInstallVkd3d: true,
autoInstallDxvkNvapi: false,
addSteamShortcuts: false,
preferSystemLibs: false,
checkForUpdatesOnStartup: !isFlatpak,
Expand Down
11 changes: 11 additions & 0 deletions src/backend/launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ async function prepareWineLaunch(
if (gameSettings.autoInstallDxvk) {
await DXVK.installRemove(gameSettings, 'dxvk', 'backup')
}
if (gameSettings.autoInstallDxvkNvapi) {
await DXVK.installRemove(gameSettings, 'dxvk-nvapi', 'backup')
}
if (gameSettings.autoInstallVkd3d) {
await DXVK.installRemove(gameSettings, 'vkd3d', 'backup')
}
Expand Down Expand Up @@ -394,6 +397,14 @@ function setupWineEnvVars(
if (!gameSettings.enableFsync && wineVersion.type === 'proton') {
ret.PROTON_NO_FSYNC = '1'
}
if (gameSettings.autoInstallDxvkNvapi && wineVersion.type === 'proton') {
ret.PROTON_ENABLE_NVAPI = '1'
ret.DXVK_NVAPI_ALLOW_OTHER_DRIVERS = '1'
}
if (gameSettings.autoInstallDxvkNvapi && wineVersion.type === 'wine') {
ret.DXVK_ENABLE_NVAPI = '1'
ret.DXVK_NVAPI_ALLOW_OTHER_DRIVERS = '1'
}
if (gameSettings.eacRuntime) {
ret.PROTON_EAC_RUNTIME = join(runtimePath, 'eac_runtime')
}
Expand Down
8 changes: 8 additions & 0 deletions src/backend/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,14 @@ ipcMain.handle('toggleDXVK', async (event, { appName, action }) =>
)
)

ipcMain.handle('toggleDXVKNVAPI', async (event, { appName, action }) =>
GameConfig.get(appName)
.getSettings()
.then(async (gameSettings) =>
DXVK.installRemove(gameSettings, 'dxvk-nvapi', action)
)
)

ipcMain.on('toggleVKD3D', (event, { appName, action }) => {
GameConfig.get(appName)
.getSettings()
Expand Down
107 changes: 100 additions & 7 deletions src/backend/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
rm
} from 'graceful-fs'
import { exec, spawn } from 'child_process'

import { execAsync, getWineFromProton } from './utils'
import {
execOptions,
Expand All @@ -29,6 +28,7 @@ import { runWineCommand, validWine } from './launcher'
import { chmod } from 'fs/promises'
import {
any_gpu_supports_version,
get_nvngx_path,
get_vulkan_instance_version
} from './utils/graphics/vulkan'
import { lt as semverLt } from 'semver'
Expand Down Expand Up @@ -59,6 +59,12 @@ export const DXVK = {
extractCommand: 'tar -xf',
os: 'linux'
},
{
name: 'dxvk-nvapi',
url: 'https://api.github.com/repos/jp7677/dxvk-nvapi/releases/latest',
extractCommand: 'tar --one-top-level -xf',
os: 'linux'
},
{
name: 'dxvk-macOS',
url: 'https://api.github.com/repos/Gcenx/DXVK-macOS/releases/latest',
Expand Down Expand Up @@ -137,7 +143,7 @@ export const DXVK = {

installRemove: async (
gameSettings: GameSettings,
tool: 'dxvk' | 'vkd3d' | 'dxvk-macOS',
tool: 'dxvk' | 'dxvk-nvapi' | 'vkd3d' | 'dxvk-macOS',
action: 'backup' | 'restore'
): Promise<boolean> => {
if (gameSettings.wineVersion.bin.includes('toolkit')) {
Expand Down Expand Up @@ -173,11 +179,12 @@ export const DXVK = {
.toString()
.split('\n')[0]

const dlls = readdirSync(`${toolsPath}/${tool}/${globalVersion}/x64`)
const toolPathx32 = `${toolsPath}/${tool}/${globalVersion}/${
tool === 'vkd3d' ? 'x86' : 'x32'
}`
const dlls32 = readdirSync(toolPathx32)
const toolPathx64 = `${toolsPath}/${tool}/${globalVersion}/x64`
const dlls64 = readdirSync(toolPathx64)
const currentVersionCheck = `${winePrefix}/current_${tool}`
let currentVersion = ''

Expand All @@ -203,7 +210,24 @@ export const DXVK = {
logInfo('Removing DLL overrides', LogPrefix.DXVKInstaller)

// unregister the dlls on the wine prefix
dlls.forEach(async (dll) => {
dlls64.forEach(async (dll) => {
dll = dll.replace('.dll', '')
const unregisterDll = [
'reg',
'delete',
'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides',
'/v',
dll,
'/f'
]
await runWineCommand({
gameSettings,
commandParts: unregisterDll,
wait: true,
protonVerb: 'waitforexitandrun'
})
})
dlls32.forEach(async (dll) => {
dll = dll.replace('.dll', '')
const unregisterDll = [
'reg',
Expand Down Expand Up @@ -231,7 +255,7 @@ export const DXVK = {
}

// copy the new dlls to the prefix
dlls.forEach((dll) => {
dlls32.forEach((dll) => {
if (!isMac) {
copyFile(
`${toolPathx32}/${dll}`,
Expand All @@ -246,7 +270,8 @@ export const DXVK = {
}
)
}

})
dlls64.forEach((dll) => {
copyFile(
`${toolPathx64}/${dll}`,
`${winePrefix}/drive_c/windows/system32/${dll}`,
Expand All @@ -262,7 +287,7 @@ export const DXVK = {
})

// register dlls on the wine prefix
dlls.forEach(async (dll) => {
dlls64.forEach(async (dll) => {
// remove the .dll extension otherwise will fail
dll = dll.replace('.dll', '')
const registerDll = [
Expand All @@ -282,6 +307,74 @@ export const DXVK = {
protonVerb: 'waitforexitandrun'
})
})
dlls32.forEach(async (dll) => {
// remove the .dll extension otherwise will fail
dll = dll.replace('.dll', '')
const registerDll = [
'reg',
'add',
'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides',
'/v',
dll,
'/d',
'native,builtin',
'/f'
]
await runWineCommand({
gameSettings,
commandParts: registerDll,
wait: true,
protonVerb: 'waitforexitandrun'
})
})

//locate and copy nvngx.dll to support DLSS on Nvidia GPUs
if (tool === 'dxvk-nvapi' && action === 'backup') {
try {
let nvngx_path = get_nvngx_path()
if (nvngx_path.length !== 0) {
nvngx_path += '/nvidia/wine'
const copyDlls = ['nvngx.dll', '_nvngx.dll']
copyDlls.forEach((dll) => {
copyFile(
`${nvngx_path}/${dll}`,
`${winePrefix}/drive_c/windows/system32/${dll}`,
(err) => {
if (err) {
logError(
[`Error when copying ${dll}`, err],
LogPrefix.DXVKInstaller
)
}
}
)
})
const regModNvngx = [
'reg',
'add',
'HKEY_LOCAL_MACHINE\\SOFTWARE\\NVIDIA Corporation\\Global\\NGXCore',
'/v',
'FullPath',
'/d',
'C:\\windows\\system32',
'/f'
]
await runWineCommand({
gameSettings,
commandParts: regModNvngx,
wait: true,
protonVerb: 'waitforexitandrun'
})
} else {
logWarning(
'Could not find nvngx.dll for DLSS!',
LogPrefix.DXVKInstaller
)
}
} catch (err) {
logError([`Error when finding nvngx.dll`, err], LogPrefix.DXVKInstaller)
}
}

writeFile(currentVersionCheck, globalVersion, (err) => {
if (err) {
Expand Down
10 changes: 9 additions & 1 deletion src/backend/utils/graphics/vulkan/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ function get_supported_vulkan_versions(): [
}
}

function get_nvngx_path(): string {
const result = spawnSync(vulkanHelperBin, ['nvapi-path'], {
encoding: 'utf-8'
})

return result.stdout.trim()
}

/**
* Helper function to detect if any GPU in the system supports a specified Vulkan version
* @returns The name of first the adapter supporting the target version, or `false` if none do
Expand All @@ -64,4 +72,4 @@ function any_gpu_supports_version(
return false
}

export { get_vulkan_instance_version, any_gpu_supports_version }
export { get_vulkan_instance_version, any_gpu_supports_version, get_nvngx_path }
1 change: 1 addition & 0 deletions src/common/typedefs/ipcBridge.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ interface AsyncIPCFunctions {
runner: Runner
}) => Promise<boolean>
toggleDXVK: (args: ToolArgs) => Promise<boolean>
toggleDXVKNVAPI: (args: ToolArgs) => Promise<boolean>
pathExists: (path: string) => Promise<boolean>
getGOGLaunchOptions: (appName: string) => Promise<LaunchOption[]>
getGameOverride: () => Promise<GameOverride | null>
Expand Down
1 change: 1 addition & 0 deletions src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export interface GameInfo {
export interface GameSettings {
autoInstallDxvk: boolean
autoInstallVkd3d: boolean
autoInstallDxvkNvapi: boolean
autoSyncSaves: boolean
battlEyeRuntime: boolean
DXVKFpsCap: string //Entered as string but used as number
Expand Down
69 changes: 69 additions & 0 deletions src/frontend/screens/Settings/components/AutoDXVKNVAPI.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useContext } from 'react'
import { ToggleSwitch } from 'frontend/components/UI'
import useSetting from 'frontend/hooks/useSetting'
import { useTranslation } from 'react-i18next'
import { defaultWineVersion } from '..'
import SettingsContext from '../SettingsContext'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCircleInfo } from '@fortawesome/free-solid-svg-icons'

const AutoDXVKNVAPI = () => {
const { t } = useTranslation()
const [autoInstallDXVKNVAPI, setAutoInstallDXVKNVAPI] = useSetting(
'autoInstallDxvkNvapi',
false
)
const { appName } = useContext(SettingsContext)
const [wineVersion] = useSetting('wineVersion', defaultWineVersion)
const [installingDxvkNvapi, setInstallingDxvkNvapi] = React.useState(false)

const handleAutoInstallDxvkNvapi = async () => {
let res = true
const isProton = wineVersion.type === 'proton'
setInstallingDxvkNvapi(true)

if (!isProton) {
const action = autoInstallDXVKNVAPI ? 'restore' : 'backup'
res = await window.api.toggleDXVKNVAPI({
appName,
action
})
}

setInstallingDxvkNvapi(false)
if (res) {
setAutoInstallDXVKNVAPI(!autoInstallDXVKNVAPI)
}
}

return (
<div className="toggleRow">
<ToggleSwitch
htmlId="autodxvknvapi"
value={autoInstallDXVKNVAPI}
handleChange={handleAutoInstallDxvkNvapi}
title={
installingDxvkNvapi
? t('please-wait', 'Please wait...')
: t(
'setting.autodxvknvapi',
'Auto Install/Update DXVK-NVAPI on Prefix'
)
}
fading={installingDxvkNvapi}
disabled={installingDxvkNvapi}
/>

<FontAwesomeIcon
className="helpIcon"
icon={faCircleInfo}
title={t(
'help.dxvknvapi',
'DXVK-NVAPI is an implementation of NVAPI built on top of DXVK and the linux native NVAPI, it allows for the usage of DLSS on Nvidia GPUs.'
)}
/>
</div>
)
}

export default AutoDXVKNVAPI
1 change: 1 addition & 0 deletions src/frontend/screens/Settings/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { default as AltGOGdlBin } from './AltGOGdlBin'
export { default as AltLegendaryBin } from './AltLegendaryBin'
export { default as AltNileBin } from './AltNileBin'
export { default as AutoDXVK } from './AutoDXVK'
export { default as AutoDXVKNVAPI } from './AutoDXVKNVAPI'
export { default as AutoUpdateGames } from './AutoUpdateGames'
export { default as AutoVKD3D } from './AutoVKD3D'
export { default as BattlEyeRuntime } from './BattlEyeRuntime'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next'
import {
AlternativeExe,
AutoDXVK,
AutoDXVKNVAPI,
AutoVKD3D,
BattlEyeRuntime,
CrossoverBottle,
Expand Down Expand Up @@ -97,6 +98,8 @@ export default function GamesSettings({ useDetails = true }: Props) {
<AutoDXVK />
{isLinux && (
<>
<AutoDXVKNVAPI />

<AutoVKD3D />

<EacRuntime />
Expand Down