Compare commits

...

23 Commits

Author SHA1 Message Date
Andrew Eikum
b4969b6b2e update vkd3d-proton to v2.3.1-39-gec5b4cce 2021-06-02 12:56:12 -05:00
Andrew Eikum
d19df7e1e8 update wine 2021-06-02 10:55:48 -05:00
Liam Middlebrook
99276ff00f 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>
2021-06-02 10:55:48 -05:00
Liam Middlebrook
9e555b222c dxvk-nvapi: Add to Proton
Add https://github.com/jp7677/dxvk-nvapi as a submodule. dxvk-nvapi will
not be copied into Proton prefixes by default, but instead will be
controlled via the environment variable PROTON_ENABLE_NVAPI. This is
done to avoid any potential adverse effects of the nvapi DLL existing
in cases where an application may require a function that is not
implemented by dxvk-nvapi.

This new functionality can be enabled by setting the following environment
variable to a value of `1`:
    `PROTON_ENABLE_NVAPI`

This functionality is needed in order to support DLSS within Proton.

Reviewed-by: Adam Moss <amoss@nvidia.com>
2021-06-02 10:40:59 -05:00
Andrew Eikum
aeecd6e2e9 proton: Use DXVK's DXGI by default 2021-06-02 10:40:59 -05:00
Andrew Eikum
c3102a9fa2 update dxvk to v1.8.1-137-gf4cbc9ae 2021-06-02 10:40:59 -05:00
Andrew Eikum
517d9edf1a Makefile: Don't consider proton-sdk tags for build name 2021-06-02 10:40:59 -05:00
Giovanni Mascellani
c6fa32fcff
docker: Install Capstone development files. 2021-05-27 16:40:49 +02:00
Andrew Eikum
0a5eb64509 update wine 2021-05-21 10:58:34 -05:00
Andrew Eikum
6a945cf0d6 update dxvk to v1.8.1-84-gc5108006 2021-05-21 10:15:42 -05:00
Andrew Eikum
3bcd985ee1 proton: Add PROTON_CRASH_REPORT_DIR runtime config
CW-Bug-Id: 18905
2021-05-21 10:13:39 -05:00
Renaud Lepage
657105b1eb proton: Assume STEAM_COMPAT_CLIENT_INSTALL_PATH is always set 2021-05-21 10:13:38 -05:00
Rémi Bernon
29f66cc1fd
docker: Add python3-pefile package to SDK image. 2021-05-21 10:23:02 +02:00
Rémi Bernon
1ece01b6cc
docker: Don't install tini, it's already there now. 2021-05-21 10:23:02 +02:00
Rémi Bernon
f93d5a355a
docker: Install libxpresent-dev packages. 2021-05-21 10:23:02 +02:00
Rémi Bernon
1bcc015a0e
docker: Bump steamrt version to 0.20210505.0. 2021-05-21 10:23:02 +02:00
Andrew Eikum
9bbfa41b86 update wine 2021-05-17 10:00:09 -05:00
Andrew Eikum
cb02bf9963 update dxvk 2021-05-14 12:18:44 -05:00
Andrew Eikum
976573ffae update vkd3d-proton to v2.3.1-8-g8734589e 2021-05-14 12:18:44 -05:00
Paul Gofman
f6b1410ab6 build: Fixup PE section headers.
For FH4.
2021-05-14 12:18:44 -05:00
Andrew Eikum
42fc3f48cc Handle steampipe quirks in deploy builds 2021-05-14 12:18:44 -05:00
Andrew Eikum
73847480a7 Don't ship filenames with colons in them 2021-05-14 12:18:44 -05:00
Andrew Eikum
3e8f844095 Don't ship proton dist files in a tarball anymore 2021-05-14 12:18:44 -05:00
16 changed files with 401 additions and 68 deletions

3
.gitmodules vendored
View File

@ -31,3 +31,6 @@
[submodule "OpenXR-SDK"]
path = OpenXR-SDK
url = https://github.com/KhronosGroup/OpenXR-SDK
[submodule "dxvk-nvapi"]
path = dxvk-nvapi
url = https://github.com/jp7677/dxvk-nvapi

View File

@ -17,7 +17,7 @@ STEAM_DIR := $(HOME)/.steam/root
BUILD_DIR := $(_build_name)
ifeq ($(build_name),)
DEPLOY_DIR := $(shell git describe --tags --always)
DEPLOY_DIR := $(shell git describe --tags --always --exclude proton-sdk*)
else
DEPLOY_DIR := $(_build_name)
endif
@ -124,17 +124,20 @@ proton: configure
install: configure
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) STEAM_DIR=/vagrant/ install'
mkdir -p $(STEAM_DIR)/compatibilitytools.d/
rm -rf $(STEAM_DIR)/compatibilitytools.d/$(_build_name)/files/ #remove proton's internal files, but preserve user_settings etc from top-level
cp -Rf --no-dereference --preserve=mode,links vagrant_share/compatibilitytools.d/$(_build_name) $(STEAM_DIR)/compatibilitytools.d/
echo "Proton installed to your local Steam installation"
redist: configure
mkdir -p vagrant_share/$(DEPLOY_DIR)
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) redist && cp $(BUILD_DIR)/redist/* /vagrant/$(DEPLOY_DIR)'
rm -rf vagrant_share/$(DEPLOY_DIR)/*
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) redist && cp -Rf $(BUILD_DIR)/redist/* /vagrant/$(DEPLOY_DIR)'
echo "Proton build available at vagrant_share/$(DEPLOY_DIR)"
deploy: configure
mkdir -p vagrant_share/$(DEPLOY_DIR)-deploy
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) deploy && cp $(BUILD_DIR)/deploy/* /vagrant/$(DEPLOY_DIR)-deploy'
rm -rf vagrant_share/$(DEPLOY_DIR)-deploy/*
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) deploy && cp -Rf $(BUILD_DIR)/deploy/* /vagrant/$(DEPLOY_DIR)-deploy'
echo "Proton deployed to vagrant_share/$(DEPLOY_DIR)-deploy"
module: configure
@ -142,6 +145,7 @@ module: configure
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) module=$(module) module && \
cp -f $(BUILD_DIR)/obj-wine32/dlls/$(module)/$(module)$(MODULE_SFX)* /vagrant/$(module)/lib/wine/ && \
cp -f $(BUILD_DIR)/obj-wine64/dlls/$(module)/$(module)$(MODULE_SFX)* /vagrant/$(module)/lib64/wine/ && \
find /vagrant/$(module)/ -type f -name "*.dll" -printf "%p\0" | xargs --verbose -0 -r -P8 -n3 proton/make/pefixup.py && \
if [ -e $(BUILD_DIR)/obj-wine64/dlls/$(module)/$(module).so ]; then \
cp -f $(BUILD_DIR)/obj-wine32/dlls/$(module)/$(module).so /vagrant/$(module)/lib/wine/ && \
cp -f $(BUILD_DIR)/obj-wine64/dlls/$(module)/$(module).so /vagrant/$(module)/lib64/wine/; \
@ -152,31 +156,41 @@ dxvk: configure
mkdir -p vagrant_share/dxvk/lib/wine/dxvk/
mkdir -p vagrant_share/dxvk/lib64/wine/dxvk/
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) dxvk && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/dxvk/*.dll /vagrant/dxvk/lib/wine/dxvk/ && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/dxvk/*.dll /vagrant/dxvk/lib64/wine/dxvk/'
cp -f $(BUILD_DIR)/dist/files/lib/wine/dxvk/*.dll /vagrant/dxvk/lib/wine/dxvk/ && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/dxvk/*.dll /vagrant/dxvk/lib64/wine/dxvk/ && \
find /vagrant/dxvk/ -type f -name "*.dll" -printf "%p\0" | xargs --verbose -0 -r -P8 -n3 proton/make/pefixup.py'
dxvk-nvapi: configure
mkdir -p vagrant_share/dxvk-nvapi/lib/wine/nvapi/
mkdir -p vagrant_share/dxvk-nvapi/lib64/wine/nvapi/
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) dxvk-nvapi && \
cp -f $(BUILD_DIR)/dist/files/lib/wine/nvapi/*.dll /vagrant/dxvk-nvapi/lib/wine/nvapi/ && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/nvapi/*.dll /vagrant/dxvk-nvapi/lib64/wine/nvapi/ && \
find /vagrant/dxvk-nvapi/ -type f -name "*.dll" -printf "%p\0" | xargs --verbose -0 -r -P8 -n3 proton/make/pefixup.py'
vkd3d-proton: configure
mkdir -p vagrant_share/vkd3d-proton/lib/wine/vkd3d-proton/
mkdir -p vagrant_share/vkd3d-proton/lib64/wine/vkd3d-proton/
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) vkd3d-proton && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/vkd3d-proton/*.dll /vagrant/vkd3d-proton/lib/wine/vkd3d-proton/ && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/vkd3d-proton/*.dll /vagrant/vkd3d-proton/lib64/wine/vkd3d-proton/'
cp -f $(BUILD_DIR)/dist/files/lib/wine/vkd3d-proton/*.dll /vagrant/vkd3d-proton/lib/wine/vkd3d-proton/ && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/vkd3d-proton/*.dll /vagrant/vkd3d-proton/lib64/wine/vkd3d-proton/ && \
find /vagrant/vkd3d-proton/ -type f -name "*.dll" -printf "%p\0" | xargs --verbose -0 -r -P8 -n3 proton/make/pefixup.py'
lsteamclient: configure
mkdir -p vagrant_share/lsteamclient/lib/wine
mkdir -p vagrant_share/lsteamclient/lib64/wine
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) lsteamclient && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/lsteamclient.dll.so /vagrant/lsteamclient/lib/wine && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/lsteamclient.dll.so /vagrant/lsteamclient/lib64/wine'
cp -f $(BUILD_DIR)/dist/files/lib/wine/lsteamclient.dll.so /vagrant/lsteamclient/lib/wine && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/lsteamclient.dll.so /vagrant/lsteamclient/lib64/wine'
vrclient: configure
mkdir -p vagrant_share/vrclient/lib/wine
mkdir -p vagrant_share/vrclient/lib64/wine
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) vrclient && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/vrclient.dll.so /vagrant/vrclient/lib/wine && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/vrclient_x64.dll.so /vagrant/vrclient/lib64/wine'
cp -f $(BUILD_DIR)/dist/files/lib/wine/vrclient.dll.so /vagrant/vrclient/lib/wine && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/vrclient_x64.dll.so /vagrant/vrclient/lib64/wine'
wineopenxr: configure
mkdir -p vagrant_share/wineopenxr/lib64/wine
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) wineopenxr && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/wineopenxr.dll.so /vagrant/wineopenxr/lib64/wine'
cp -f $(BUILD_DIR)/dist/files/lib64/wine/wineopenxr.dll.so /vagrant/wineopenxr/lib64/wine'

View File

@ -270,12 +270,14 @@ the Wine prefix. Removing the option will revert to the previous behavior.
| | <tt>PROTON_LOG_DIR</tt> | Output log files into the directory specified. Defaults to your home directory. |
| | <tt>PROTON_DUMP_DEBUG_COMMANDS</tt> | When running a game, Proton will write some useful debug scripts for that game into `$PROTON_DEBUG_DIR/proton_$USER/`. |
| | <tt>PROTON_DEBUG_DIR</tt> | Root directory for the Proton debug scripts, `/tmp` by default. |
| | <tt>PROTON_CRASH_REPORT_DIR</tt> | Write crash logs into this directory. Does not clean up old logs, so may eat all your disk space eventually. |
| <tt>wined3d</tt> | <tt>PROTON_USE_WINED3D</tt> | Use OpenGL-based wined3d instead of Vulkan-based DXVK for d3d11, d3d10, and d3d9. |
| <tt>nod3d11</tt> | <tt>PROTON_NO_D3D11</tt> | Disable <tt>d3d11.dll</tt>, for d3d11 games which can fall back to and run better with d3d9. |
| <tt>nod3d10</tt> | <tt>PROTON_NO_D3D10</tt> | Disable <tt>d3d10.dll</tt> and <tt>dxgi.dll</tt>, for d3d10 games which can fall back to and run better with d3d9. |
| <tt>noesync</tt> | <tt>PROTON_NO_ESYNC</tt> | Do not use eventfd-based in-process synchronization primitives. |
| <tt>nofsync</tt> | <tt>PROTON_NO_FSYNC</tt> | Do not use futex-based in-process synchronization primitives. (Automatically disabled on systems with no `FUTEX_WAIT_MULTIPLE` support.) |
| <tt>noxim</tt> | <tt>PROTON_NO_XIM</tt> | Enabled by default. Do not attempt to use XIM (X Input Methods) support. XIM support is known to cause crashes with libx11 older than version 1.7. |
| <tt>enablenvapi</tt> | <tt>PROTON_ENABLE_NVAPI</tt> | Enable NVIDIA's NVAPI GPU support library. |
| <tt>nativevulkanloader</tt> | | Use the Vulkan loader shipped with the game instead of Proton's built-in Vulkan loader. This breaks VR support, but is required by a few games. |
| <tt>forcelgadd</tt> | <tt>PROTON_FORCE_LARGE_ADDRESS_AWARE</tt> | Force Wine to enable the LARGE_ADDRESS_AWARE flag for all executables. Enabled by default. |
| <tt>heapdelayfree</tt>| <tt>PROTON_HEAP_DELAY_FREE</tt>| Delay freeing some memory, to work around application use-after-free bugs. |

2
Vagrantfile vendored
View File

@ -77,7 +77,7 @@ Vagrant.configure(2) do |config|
#install host build-time dependencies
apt-get update
apt-get install -y ccache texinfo gpgv2 gnupg2 git docker-ce docker-ce-cli containerd.io \
fontforge-nox python-debian python-pip
fontforge-nox python-debian python-pip python3-pefile
#install adobe font devkit to build source san hans
pip install afdko

View File

@ -113,7 +113,7 @@ endif
##
DST_BASE := $(OBJ)/dist
DST_DIR := $(DST_BASE)/dist
DST_DIR := $(DST_BASE)/files
DST_LIBDIR32 := $(DST_DIR)/lib
DST_LIBDIR64 := $(DST_DIR)/lib64
DEPLOY_DIR := ./deploy
@ -155,6 +155,7 @@ CARGO_BUILD_ARG := --release
COMPAT_MANIFEST_TEMPLATE := $(SRCDIR)/compatibilitytool.vdf.template
LICENSE := $(SRCDIR)/dist.LICENSE
OFL_LICENSE := $(SRCDIR)/fonts/liberation-fonts/LICENSE
STEAMPIPE_FIXUPS_PY := $(SRCDIR)/steampipe_fixups.py
GECKO_VER := 2.47.2
GECKO32_TARBALL := wine-gecko-$(GECKO_VER)-x86.tar.xz
@ -241,8 +242,9 @@ DIST_TARGETS := $(DIST_COPY_TARGETS) $(DIST_OVR32) $(DIST_OVR64) \
$(DIST_GECKO32) $(DIST_GECKO64) $(DIST_WINEMONO) \
$(DIST_COMPAT_MANIFEST) $(DIST_LICENSE) $(DIST_TOOLMANIFEST) $(DIST_OFL_LICENSE) $(DIST_FONTS)
DEPLOY_COPY_TARGETS := $(DIST_COPY_TARGETS) $(DIST_VERSION) $(DIST_LICENSE) $(DIST_TOOLMANIFEST) $(DIST_OFL_LICENSE)
REDIST_COPY_TARGETS := $(DEPLOY_COPY_TARGETS) $(DIST_COMPAT_MANIFEST)
BASE_COPY_TARGETS := $(DIST_COPY_TARGETS) $(DIST_VERSION) $(DIST_LICENSE) $(DIST_TOOLMANIFEST) $(DIST_OFL_LICENSE) $(DST_DIR)
DEPLOY_COPY_TARGETS := $(BASE_COPY_TARGETS) $(STEAMPIPE_FIXUPS_PY)
REDIST_COPY_TARGETS := $(BASE_COPY_TARGETS) $(DIST_COMPAT_MANIFEST)
$(DIST_LICENSE): $(LICENSE)
cp -a $< $@
@ -331,24 +333,20 @@ dist: $(DIST_TARGETS) all-dist dist_wineopenxr | $(DST_DIR)
echo `date '+%s'` `GIT_DIR=$(abspath $(SRCDIR)/.git) git describe --tags` > $(DIST_VERSION)
deploy: dist | $(filter-out dist deploy install redist,$(MAKECMDGOALS))
mkdir -p $(DEPLOY_DIR) && \
cp -a $(DEPLOY_COPY_TARGETS) $(DEPLOY_DIR) && \
tar -C $(DST_DIR) -c . > $(DEPLOY_DIR)/proton_dist.tar
@echo "Created deployment archive at "$(DEPLOY_DIR)"/proton_dist.tar"
mkdir -p $(DEPLOY_DIR)
cp -af --no-dereference --preserve=mode,links $(DEPLOY_COPY_TARGETS) $(DEPLOY_DIR)
python3 $(STEAMPIPE_FIXUPS_PY) process $(DEPLOY_DIR)
install: dist | $(filter-out dist deploy install redist,$(MAKECMDGOALS))
if [ ! -d $(STEAM_DIR) ]; then echo >&2 "!! "$(STEAM_DIR)" does not exist, cannot install"; return 1; fi
mkdir -p $(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)
cp -rf --no-dereference --preserve=mode,links $(DST_BASE)/* $(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)
cp -f $(DIST_VERSION) $(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)/dist/
cp -af --no-dereference --preserve=mode,links $(DST_BASE)/* $(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)
@echo "Installed Proton to "$(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)
@echo "You may need to restart Steam to select this tool"
redist: dist | $(filter-out dist deploy install redist,$(MAKECMDGOALS))
mkdir -p $(REDIST_DIR)
cp -a $(REDIST_COPY_TARGETS) $(REDIST_DIR)
tar -C $(DST_DIR) -c . | gzip -c -1 > $(REDIST_DIR)/proton_dist.tar.gz
@echo "Created redistribution tarball at "$(REDIST_DIR)"/proton_dist.tar.gz"
cp -af --no-dereference --preserve=mode,links $(REDIST_COPY_TARGETS) $(REDIST_DIR)
.PHONY: module32 module64 module
@ -701,6 +699,32 @@ $(OBJ)/.dxvk-post-build32:
touch $@
##
## dxvk-nvapi
##
DXVK_NVAPI_MESON_ARGS32 = \
--bindir=$(DXVK_NVAPI_DST32)/lib/wine/nvapi \
--cross-file=$(DXVK_NVAPI_OBJ32)/build-win32.txt
DXVK_NVAPI_MESON_ARGS64 = \
--bindir=$(DXVK_NVAPI_DST64)/lib64/wine/nvapi \
--cross-file=$(DXVK_NVAPI_OBJ64)/build-win64.txt
$(eval $(call rules-source,dxvk-nvapi,$(SRCDIR)/dxvk-nvapi))
$(eval $(call rules-meson,dxvk-nvapi,32))
$(eval $(call rules-meson,dxvk-nvapi,64))
$(OBJ)/.dxvk-nvapi-post-build64:
mkdir -p "$(DST_DIR)"/lib64/wine/nvapi
rm -f "$(DST_DIR)"/lib64/wine/nvapi/version && if test -e $(SRCDIR)/.git; then ( cd $(SRCDIR) && git submodule status -- dxvk-nvapi ) > "$(DST_DIR)"/lib64/wine/nvapi/version; fi
touch $@
$(OBJ)/.dxvk-nvapi-post-build32:
mkdir -p "$(DST_DIR)"/lib/wine/nvapi
rm -f "$(DST_DIR)"/lib/wine/nvapi/version && if test -e $(SRCDIR)/.git; then ( cd $(SRCDIR) && git submodule status -- dxvk-nvapi ) > "$(DST_DIR)"/lib/wine/nvapi/version; fi
touch $@
##
## vkd3d-proton
##

View File

@ -73,6 +73,14 @@ def setup_dll_symlinks(default_pfx_dir, dist_dir):
os.unlink(filename)
make_relative_symlink(target, filename)
#steampipe can't handle filenames with colons, so we remove them here
#and restore them in the proton script
def fixup_drive_links(default_pfx_dir):
for walk_dir, dirs, files in os.walk(os.path.join(default_pfx_dir, "dosdevices")):
for dir_ in dirs:
if ":" in dir_:
os.remove(os.path.join(walk_dir, dir_))
def make_default_pfx(default_pfx_dir, dist_dir, runtime):
local_env = dict(os.environ)
@ -96,6 +104,7 @@ def make_default_pfx(default_pfx_dir, dist_dir, runtime):
env=local_env, check=True)
setup_dll_symlinks(default_pfx_dir, dist_dir)
fixup_drive_links(default_pfx_dir)
if __name__ == '__main__':
import sys

View File

@ -1,4 +1,4 @@
STEAMRT_VERSION = 0.20210126.1
STEAMRT_VERSION = 0.20210505.0
STEAMRT_URLBASE = registry.gitlab.steamos.cloud
PROTONSDK_URLBASE = $(STEAMRT_URLBASE)/proton/soldier/sdk

View File

@ -52,9 +52,14 @@ RUN bash -c 'mkdir -p /usr/lib/ccache && ls /usr/bin/{,*-}{cc,c++,gcc,g++}{,-[0-
ENV PATH=/usr/lib/ccache:$PATH
RUN apt-get install -y \
tini \
libxpresent-dev \
libxpresent-dev:i386 \
python3-pefile \
libcapstone-dev \
libcapstone-dev:i386 \
&& rm -rf /opt/usr/share/doc /opt/usr/share/info /opt/usr/share/man \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/usr/bin/tini-static", "-s", "-g", "--"]
CMD ["/bin/bash"]

2
dxvk

@ -1 +1 @@
Subproject commit f8a4ca555a6e5d89f5162a042bbae550902f4e49
Subproject commit ed3aacadb27918e7988e479a275088a78e18cfa8

1
dxvk-nvapi Submodule

@ -0,0 +1 @@
Subproject commit fcd8ce2a0e5eef81148cedcb572fe6d1e667da94

27
make/pefixup.py Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/env python3
import sys
import os
import stat
import pefile
for path in sys.argv[1:]:
pe = pefile.PE(path)
for section in pe.sections:
if section.Name.decode("utf-8")[0:5] == ".text":
section.Characteristics &= ~pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_CNT_INITIALIZED_DATA']
section.Characteristics &= ~pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_ALIGN_MASK']
pe.OPTIONAL_HEADER.CheckSum = pe.generate_checksum()
perm = stat.S_IMODE(os.stat(path).st_mode)
if (perm & stat.S_IWUSR) == 0:
os.chmod(path, perm | stat.S_IWUSR)
pe.write(path)
if (perm & stat.S_IWUSR) == 0:
os.chmod(path, perm)
print("Fixed up PE: ", path)

View File

@ -82,6 +82,14 @@ endif
$(1)-dist$(3): $$(OBJ)/.$(1)-dist$(3)
.INTERMEDIATE: $(1)-dist$(3)
ifeq ($(CONTAINER),)
$(1)-dist$(3): $$(OBJ)/.$(1)-fixup$(3)
$$(OBJ)/.$(1)-fixup$(3): $$(OBJ)/.$(1)-dist$(3)
cd $$($(2)_LIBDIR$(3)) && find -type f -name '*.dll' -printf '$$(DST_LIBDIR$(3))/%p\0' | xargs --verbose -0 -r -P8 -n3 $$(SRC)/make/pefixup.py
touch $$@
endif
all-dist$(3) $(1)-dist: $(1)-dist$(3)
.PHONY: all-dist$(3) $(1)-dist

200
proton
View File

@ -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
@ -149,14 +236,14 @@ def set_dir_casefold_bit(dir_path):
class Proton:
def __init__(self, base_dir):
self.base_dir = base_dir + "/"
self.dist_dir = self.path("dist/")
self.bin_dir = self.path("dist/bin/")
self.lib_dir = self.path("dist/lib/")
self.lib64_dir = self.path("dist/lib64/")
self.fonts_dir = self.path("dist/share/fonts/")
self.wine_fonts_dir = self.path("dist/share/wine/fonts/")
self.dist_dir = self.path("files/")
self.bin_dir = self.path("files/bin/")
self.lib_dir = self.path("files/lib/")
self.lib64_dir = self.path("files/lib64/")
self.fonts_dir = self.path("files/share/fonts/")
self.wine_fonts_dir = self.path("files/share/wine/fonts/")
self.version_file = self.path("version")
self.default_pfx_dir = self.path("dist/share/default_pfx/")
self.default_pfx_dir = self.path("files/share/default_pfx/")
self.user_settings_file = self.path("user_settings.py")
self.wine_bin = self.bin_dir + "wine"
self.wineserver_bin = self.bin_dir + "wineserver"
@ -165,28 +252,34 @@ class Proton:
def path(self, d):
return self.base_dir + d
def need_tarball_extraction(self):
'''Checks if the proton_dist tarball archive must be extracted. Returns true if extraction is needed, false otherwise'''
return not os.path.exists(self.dist_dir) or \
not os.path.exists(self.path("dist/version")) or \
not filecmp.cmp(self.version_file, self.path("dist/version"))
def cleanup_legacy_dist(self):
old_dist_dir = self.path("dist/")
if os.path.exists(old_dist_dir):
with self.dist_lock:
if os.path.exists(old_dist_dir):
shutil.rmtree(old_dist_dir)
def extract_tarball(self):
with self.dist_lock:
if self.need_tarball_extraction():
if os.path.exists(self.dist_dir):
shutil.rmtree(self.dist_dir)
tar = None
for sf in ["", ".xz", ".bz2", ".gz"]:
if os.path.exists(self.path("proton_dist.tar" + sf)):
tar = tarfile.open(self.path("proton_dist.tar" + sf), mode="r:*")
break
if not tar:
log("No proton_dist tarball??")
sys.exit(1)
tar.extractall(path=self.dist_dir)
tar.close()
try_copy(self.version_file, self.dist_dir)
def do_steampipe_fixups(self):
fixups_json = self.path("steampipe_fixups.json")
fixups_mtime = self.path("files/steampipe_fixups_mtime")
if os.path.exists(fixups_json):
with self.dist_lock:
import steampipe_fixups
current_fixup_mtime = None
if os.path.exists(fixups_mtime):
with open(fixups_mtime, "r") as f:
current_fixup_mtime = f.readline().strip()
new_fixup_mtime = getmtimestr(fixups_json)
if current_fixup_mtime != new_fixup_mtime:
result_code = steampipe_fixups.do_restore(self.base_dir, fixups_json)
if result_code == 0:
with open(fixups_mtime, "w") as f:
f.write(new_fixup_mtime + "\n")
def missing_default_prefix(self):
'''Check if the default prefix dir is missing. Returns true if missing, false if present'''
@ -432,16 +525,18 @@ class CompatData:
if not os.path.exists(self.prefix_dir + "/user.reg"):
self.copy_pfx()
if not os.path.lexists(self.prefix_dir + "/dosdevices/c:"):
os.symlink("../drive_c", self.prefix_dir + "/dosdevices/c:")
if not os.path.lexists(self.prefix_dir + "/dosdevices/z:"):
os.symlink("/", self.prefix_dir + "/dosdevices/z:")
# collect configuration info
if "STEAM_COMPAT_CLIENT_INSTALL_PATH" in os.environ:
#modern steam client sets this
steamdir = os.environ["STEAM_COMPAT_CLIENT_INSTALL_PATH"]
else:
#linux-only fallback, really shouldn't get here
steamdir = os.environ["HOME"] + ".steam/root/"
steamdir = os.environ["STEAM_COMPAT_CLIENT_INSTALL_PATH"]
use_wined3d = "wined3d" in g_session.compat_config
use_dxvk_dxgi = "WINEDLLOVERRIDES" in g_session.env and "dxgi=n" in g_session.env["WINEDLLOVERRIDES"]
use_dxvk_dxgi = not ("WINEDLLOVERRIDES" in g_session.env and "dxgi=b" in g_session.env["WINEDLLOVERRIDES"])
use_nvapi = 'enablenvapi' in g_session.compat_config
builtin_dll_copy = os.environ.get("PROTON_DLL_COPY",
#dxsetup redist
@ -486,6 +581,7 @@ class CompatData:
str(use_wined3d),
str(use_dxvk_dxgi),
builtin_dll_copy,
str(use_nvapi),
))
if old_ver == CURRENT_PREFIX_VERSION:
@ -561,7 +657,6 @@ class CompatData:
dxvkfiles = ["dxvk_config", "d3d11", "d3d10", "d3d10core", "d3d10_1", "d3d9"]
wined3dfiles = []
#if the user asked for dxvk's dxgi (dxgi=n), then copy it into place
if use_dxvk_dxgi:
dxvkfiles.append("dxgi")
else:
@ -580,6 +675,31 @@ class CompatData:
self.prefix_dir + "drive_c/windows/syswow64/" + f + ".dll")
g_session.dlloverrides[f] = "n"
# If the user requested the NVAPI be available, copy it into place.
# If they didn't, clean up any stray nvapi DLLs.
if use_nvapi:
try_copy(g_proton.lib64_dir + "wine/nvapi/nvapi64.dll",
self.prefix_dir + "drive_c/windows/system32/nvapi64.dll")
try_copy(g_proton.lib_dir + "wine/nvapi/nvapi.dll",
self.prefix_dir + "drive_c/windows/syswow64/nvapi.dll")
g_session.dlloverrides["nvapi64"] = "n"
g_session.dlloverrides["nvapi"] = "n"
else:
nvapi64_dll = self.prefix_dir + "drive_c/windows/system32/nvapi64.dll"
nvapi32_dll = self.prefix_dir + "drive_c/windows/syswow64/nvapi.dll"
if os.path.exists(nvapi64_dll):
os.unlink(nvapi64_dll)
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",
@ -745,6 +865,7 @@ class Session:
self.check_environment("PROTON_SET_GAME_DRIVE", "gamedrive")
self.check_environment("PROTON_NO_XIM", "noxim")
self.check_environment("PROTON_HEAP_DELAY_FREE", "heapdelayfree")
self.check_environment("PROTON_ENABLE_NVAPI", "enablenvapi")
if "noesync" in self.compat_config:
self.env.pop("WINEESYNC", "")
@ -784,6 +905,9 @@ class Session:
if "hidenvgpu" in self.compat_config:
self.env["WINE_HIDE_NVIDIA_GPU"] = "1"
if "PROTON_CRASH_REPORT_DIR" in self.env:
self.env["WINE_CRASH_REPORT_DIR"] = self.env["PROTON_CRASH_REPORT_DIR"]
if "SteamGameId" in self.env:
if self.env["WINEDEBUG"] != "-all":
basedir = self.env.get("PROTON_LOG_DIR", os.environ["HOME"])
@ -972,8 +1096,8 @@ if __name__ == "__main__":
g_proton = Proton(os.path.dirname(sys.argv[0]))
if g_proton.need_tarball_extraction():
g_proton.extract_tarball()
g_proton.cleanup_legacy_dist()
g_proton.do_steampipe_fixups()
g_compatdata = CompatData(os.environ["STEAM_COMPAT_DATA_PATH"])

116
steampipe_fixups.py Executable file
View File

@ -0,0 +1,116 @@
#!/usr/bin/env python3
#Steampipe doesn't support certain unix-y things which may be required by
#native Linux applications. This file will process a directory of Linux files
#and store the file properties into a manifest file. After a round trip through
#Steampipe, the original file properties can be restored using this same
#script.
import json
import os
import secrets
import stat
DEFAULT_MANIFEST_NAME = "steampipe_fixups.json"
def usage():
print("Usage:")
print("\t" + sys.argv[0] + "\tprepare\t<path to directory to process>\t[manifest output file]")
print("\t\tProcess the given path and output the manifest file to the given path, or <path/" + DEFAULT_MANIFEST_NAME + "> if unspecified.")
print("")
print("\t" + sys.argv[0] + "\trestore\t<path to directory to process>\t[manifest file]")
print("\t\tRestore the given path using the manifest file, or <path/" + DEFAULT_MANIFEST_NAME + "> if unspecified.")
empty_dirs = []
no_write_paths = []
def canonicalize(path, prefix):
return path.replace(prefix, "", 1).lstrip('/')
def process_dir(path):
for root, subdirs, files in os.walk(path):
if len(subdirs) == 0 and len(files) == 0:
empty_dirs.append(canonicalize(root, path))
for file_ in files:
this_file = os.path.join(root, file_)
stat_result = os.lstat(this_file)
if (stat_result.st_mode & stat.S_IWUSR) == 0:
no_write_paths.append(canonicalize(this_file, path))
return 0
def write_manifest(manifest):
out = open(manifest, "w")
json.dump(
{
"id": str(secrets.randbits(32)), #we need steampipe to update this file for every build
"empty_dirs": empty_dirs,
"no_write_paths": no_write_paths,
},
out,
indent = 4,
sort_keys = True
)
return 0
def do_process(path, manifest):
if os.path.exists(manifest):
os.remove(manifest)
ret = process_dir(path)
if ret != 0:
return ret
#output should be deterministic
empty_dirs.sort()
no_write_paths.sort()
ret = write_manifest(manifest)
if ret != 0:
return ret
return 0
def do_restore(path, manifest):
loaded = json.load(open(manifest, "r"))
empty_dirs = loaded["empty_dirs"]
no_write_paths = loaded["no_write_paths"]
for empty_dir in empty_dirs:
try:
os.makedirs(os.path.join(path, empty_dir))
except OSError:
#already exists
pass
for file_ in no_write_paths:
this_file = os.path.join(path, file_)
stat_result = os.lstat(this_file)
os.chmod(this_file,
stat_result.st_mode & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH))
return 0
if __name__ == '__main__':
import sys
if len(sys.argv) < 3 or len(sys.argv) > 4:
usage()
sys.exit(1)
verb = sys.argv[1]
path = sys.argv[2]
if len(sys.argv) >= 4:
manifest = sys.argv[3]
else:
manifest = os.path.join(path, DEFAULT_MANIFEST_NAME)
if verb == "process":
sys.exit(do_process(path, manifest))
if verb == "restore":
sys.exit(do_restore(path, manifest))
usage()
sys.exit(1)

@ -1 +1 @@
Subproject commit 3ed3526332f53d7d35cf1b685fa8096b01f26ff0
Subproject commit ec5b4ccecf799e7593dd3c6e8b13dc4f04e77228

2
wine

@ -1 +1 @@
Subproject commit f94b0f7590d43bb3e6aefcc6e16cf69bffc25122
Subproject commit 5b82ac53192d32fe28516abf4161d2174817b164