Skip to content

[Feature] Download DXVK 1.10.3 if no Vulkan 1.3 support is detected #2717

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 2 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@
},
"asarUnpack": [
"build/bin/linux/legendary",
"build/bin/linux/gogdl"
"build/bin/linux/gogdl",
"build/bin/linux/vulkan-helper"
],
"files": [
"build/bin/linux/*"
Expand Down Expand Up @@ -183,6 +184,7 @@
"react-router-dom": "^6.9.0",
"recharts": "^2.4.3",
"sanitize-filename": "^1.6.3",
"semver": "^7.5.1",
"shlex": "^2.1.2",
"short-uuid": "^4.2.2",
"simple-keyboard": "^3.5.33",
Expand Down
Binary file added public/bin/linux/vulkan-helper
Binary file not shown.
6 changes: 5 additions & 1 deletion src/backend/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ const { currentLogFile, lastLogFile, legendaryLogFile, gogdlLogFile } =

const publicDir = resolve(__dirname, '..', app.isPackaged ? '' : '../public')
const gogdlAuthConfig = join(app.getPath('userData'), 'gog_store', 'auth.json')
const vulkanHelperBin = fixAsarPath(
join(publicDir, 'bin', process.platform, 'vulkan-helper')
)
const icon = fixAsarPath(join(publicDir, 'icon.png'))
const iconDark = fixAsarPath(join(publicDir, 'icon-dark.png'))
const iconLight = fixAsarPath(join(publicDir, 'icon-light.png'))
Expand Down Expand Up @@ -250,5 +253,6 @@ export {
wineprefixFAQ,
customThemesWikiLink,
cachedUbisoftInstallerPath,
gogdlAuthConfig
gogdlAuthConfig,
vulkanHelperBin
}
52 changes: 50 additions & 2 deletions src/backend/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,26 @@ import {
import { exec, spawn } from 'child_process'

import { execAsync, getWineFromProton } from './utils'
import { execOptions, toolsPath, isMac, isWindows, userHome } from './constants'
import {
execOptions,
toolsPath,
isMac,
isWindows,
userHome,
isLinux
} from './constants'
import { logError, logInfo, LogPrefix, logWarning } from './logger/logger'
import i18next from 'i18next'
import { dirname, join } from 'path'
import { isOnline } from './online_monitor'
import { showDialogBoxModalAuto } from './dialog/dialog'
import { runWineCommand, validWine } from './launcher'
import { chmod } from 'fs/promises'
import {
any_gpu_supports_version,
get_vulkan_instance_version
} from './utils/graphics/vulkan'
import { lt as semverLt } from 'semver'

export const DXVK = {
getLatest: async () => {
Expand All @@ -43,7 +55,7 @@ export const DXVK = {
},
{
name: 'dxvk',
url: 'https://api.github.com/repos/doitsujin/dxvk/releases/latest',
url: getDxvkUrl(),
extractCommand: 'tar -xf',
os: 'linux'
},
Expand Down Expand Up @@ -472,3 +484,39 @@ export const Winetricks = {
)
}
}

/**
* Figures out the right DXVK version to use, taking the user's hardware
* (specifically their Vulkan support) into account
*/
function getDxvkUrl(): string {
if (!isLinux) {
return ''
}

if (any_gpu_supports_version([1, 3, 0])) {
const instance_version = get_vulkan_instance_version()
if (instance_version && semverLt(instance_version.join('.'), '1.3.0')) {
// FIXME: How does the instance version matter? Even with 1.2, newer DXVK seems to work fine
logWarning(
'Vulkan 1.3 is supported by GPUs in this system, but instance version is outdated',
LogPrefix.DXVKInstaller
)
}
return 'https://api.github.com/repos/doitsujin/dxvk/releases/latest'
}
if (any_gpu_supports_version([1, 1, 0])) {
logInfo(
'The GPU(s) in this system only support Vulkan 1.1/1.2, falling back to DXVK 1.10.3',
LogPrefix.DXVKInstaller
)
return 'https://api.github.com/repos/doitsujin/dxvk/releases/tags/v1.10.3'
}
logWarning(
'No GPU with Vulkan 1.1 support found, DXVK will not work',
LogPrefix.DXVKInstaller
)
// FIXME: We currently lack a "Don't download at all" option here, but
// that would also need bigger changes in the frontend
return 'https://api.github.com/repos/doitsujin/dxvk/releases/latest'
}
67 changes: 67 additions & 0 deletions src/backend/utils/graphics/vulkan/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { vulkanHelperBin } from 'backend/constants'
import { spawnSync } from 'child_process'
import { gte as semverGte } from 'semver'

type VulkanVersion = [maj: number, min: number, patch: number]

/**
* @returns The version of the installed Vulkan API interface, or `false` if
* unsupported. <br>
* Note that this is the interface version, not the version a user's GPU(s)
* support. For that, see {@link get_supported_vulkan_versions}
*/
function get_vulkan_instance_version(): VulkanVersion | false {
const result = spawnSync(vulkanHelperBin, ['instance-version'], {
encoding: 'utf-8'
})

try {
return JSON.parse(result.stdout) as VulkanVersion
} catch {
return false
}
}

/**
* @returns A list of device names and their supported Vulkan versions
*/
function get_supported_vulkan_versions(): [
name: string,
version: VulkanVersion
][] {
const result = spawnSync(vulkanHelperBin, ['physical-versions'], {
encoding: 'utf-8'
})

try {
const output = JSON.parse(result.stdout) as Array<{
name: string
major: number
minor: number
patch: number
}>
return output.map(({ name, major, minor, patch }) => [
name,
[major, minor, patch]
])
} catch {
return []
}
}

/**
* 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
*/
function any_gpu_supports_version(
target_version: VulkanVersion
): string | false {
for (const [name, supported_version] of get_supported_vulkan_versions()) {
if (semverGte(supported_version.join('.'), target_version.join('.'))) {
return name
}
}
return false
}

export { get_vulkan_instance_version, any_gpu_supports_version }
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7451,6 +7451,13 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==

semver@^7.5.1:
version "7.5.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec"
integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==
dependencies:
lru-cache "^6.0.0"

semver@~7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
Expand Down