mirror of
https://github.com/ValveSoftware/Proton.git
synced 2025-07-29 16:41:53 +03:00
proton: Copy DLLs provided by the NVIDIA driver into prefix
The upcoming NVIDIA 470 driver series will introduce a DLL (nvngx.dll) for the support of NVIDIA DLSS in Proton. This change adds logic for discovering the location of DLL files provided by the NVIDIA driver, and copies them to C:\Windows\System32\ Reviewed-by: Adam Moss <amoss@nvidia.com>
This commit is contained in:
parent
9e555b222c
commit
99276ff00f
95
proton
95
proton
@ -15,6 +15,16 @@ import subprocess
|
||||
import sys
|
||||
import tarfile
|
||||
|
||||
from ctypes import CDLL
|
||||
from ctypes import POINTER
|
||||
from ctypes import Structure
|
||||
from ctypes import addressof
|
||||
from ctypes import cast
|
||||
from ctypes import c_int
|
||||
from ctypes import c_char_p
|
||||
from ctypes import c_void_p
|
||||
from ctypes.util import find_library
|
||||
|
||||
from filelock import FileLock
|
||||
|
||||
#To enable debug logging, copy "user_settings.sample.py" to "user_settings.py"
|
||||
@ -127,6 +137,83 @@ def try_get_game_library_dir():
|
||||
|
||||
return None
|
||||
|
||||
# Function to find the installed location of DLL files for use by Wine/Proton
|
||||
# from the NVIDIA Linux driver
|
||||
#
|
||||
# See https://gitlab.steamos.cloud/steamrt/steam-runtime-tools/-/issues/71 for
|
||||
# background on the chosen method of DLL discovery.
|
||||
#
|
||||
# On success, returns a str() of the absolute-path to the directory at which DLL
|
||||
# files are stored
|
||||
#
|
||||
# On failure, returns None
|
||||
def find_nvidia_wine_dll_dir():
|
||||
libdl = CDLL(find_library("libdl"))
|
||||
libglx_nvidia = CDLL("libGLX_nvidia.so.0")
|
||||
|
||||
if libdl is None or libglx_nvidia is None:
|
||||
return None
|
||||
|
||||
# from dlinfo(3)
|
||||
#
|
||||
# struct link_map {
|
||||
# ElfW(Addr) l_addr; /* Difference between the
|
||||
# address in the ELF file and
|
||||
# the address in memory */
|
||||
# char *l_name; /* Absolute pathname where
|
||||
# object was found */
|
||||
# ElfW(Dyn) *l_ld; /* Dynamic section of the
|
||||
# shared object */
|
||||
# struct link_map *l_next, *l_prev;
|
||||
# /* Chain of loaded objects */
|
||||
#
|
||||
# /* Plus additional fields private to the
|
||||
# implementation */
|
||||
# };
|
||||
RTLD_DI_LINKMAP = 2
|
||||
class link_map(Structure):
|
||||
_fields_ = [("l_addr", c_void_p), ("l_name", c_char_p), ("l_ld", c_void_p)]
|
||||
|
||||
# from dlinfo(3)
|
||||
#
|
||||
# int dlinfo (void *restrict handle, int request, void *restrict info)
|
||||
dlinfo_func = libdl.dlinfo
|
||||
dlinfo_func.argtypes = c_void_p, c_int, c_void_p
|
||||
dlinfo_func.restype = c_int
|
||||
|
||||
# Allocate a link_map object
|
||||
glx_nvidia_info_ptr = POINTER(link_map)()
|
||||
|
||||
# Run dlinfo(3) on the handle to libGLX_nvidia.so.0, storing results at the
|
||||
# address represented by glx_nvidia_info_ptr
|
||||
if dlinfo_func(libglx_nvidia._handle,
|
||||
RTLD_DI_LINKMAP,
|
||||
addressof(glx_nvidia_info_ptr)) != 0:
|
||||
return None
|
||||
|
||||
# Grab the contents our of our pointer
|
||||
glx_nvidia_info = cast(glx_nvidia_info_ptr, POINTER(link_map)).contents
|
||||
|
||||
# Decode the path to our library to a str()
|
||||
if glx_nvidia_info.l_name is None:
|
||||
return None
|
||||
try:
|
||||
libglx_nvidia_path = os.fsdecode(glx_nvidia_info.l_name)
|
||||
except UnicodeDecodeError:
|
||||
return None
|
||||
|
||||
# Follow any symlinks to the actual file
|
||||
libglx_nvidia_realpath = os.path.realpath(libglx_nvidia_path)
|
||||
|
||||
# Go to the relative path ./nvidia/wine from our library
|
||||
nvidia_wine_dir = os.path.join(os.path.dirname(libglx_nvidia_realpath), "nvidia", "wine")
|
||||
|
||||
# Check that nvngx.dll exists here, or fail
|
||||
if os.path.exists(os.path.join(nvidia_wine_dir, "nvngx.dll")):
|
||||
return nvidia_wine_dir
|
||||
|
||||
return None
|
||||
|
||||
EXT2_IOC_GETFLAGS = 0x80086601
|
||||
EXT2_IOC_SETFLAGS = 0x40086602
|
||||
|
||||
@ -605,6 +692,14 @@ class CompatData:
|
||||
if os.path.exists(nvapi32_dll):
|
||||
os.unlink(nvapi32_dll)
|
||||
|
||||
# Try to detect known DLLs that ship with the NVIDIA Linux Driver
|
||||
# and add them into the prefix
|
||||
nvidia_wine_dll_dir = find_nvidia_wine_dll_dir()
|
||||
if nvidia_wine_dll_dir:
|
||||
for dll in ["_nvngx.dll", "nvngx.dll"]:
|
||||
try_copy(nvidia_wine_dll_dir + "/" + dll,
|
||||
self.prefix_dir + "drive_c/windows/system32/" + dll)
|
||||
|
||||
try_copy(g_proton.lib64_dir + "wine/vkd3d-proton/d3d12.dll",
|
||||
self.prefix_dir + "drive_c/windows/system32/d3d12.dll")
|
||||
try_copy(g_proton.lib_dir + "wine/vkd3d-proton/d3d12.dll",
|
||||
|
Loading…
x
Reference in New Issue
Block a user