From 59d5307caed77c8a924a8a85f7972390df1f84c0 Mon Sep 17 00:00:00 2001 From: Randy Eckenrode Date: Mon, 25 Mar 2024 14:33:28 -0400 Subject: [PATCH] dxvk: switch to Win32 thread model and cleanups - Reformat per RFC-166; - Update setup script to report on and offer to clean up obsolete mcfgthread DLL; - Switch DXVK to thread model to Win32 from MCF; and - Clean up Meson build configuration. --- pkgs/by-name/dx/dxvk/package.nix | 83 ++++++++++++++++++++-------- pkgs/by-name/dx/dxvk/setup_dxvk.sh | 89 ++++++++++++++++++++++++++---- pkgs/by-name/dx/dxvk_1/package.nix | 60 ++++++++++++-------- pkgs/by-name/dx/dxvk_2/package.nix | 56 +++++++++++-------- 4 files changed, 211 insertions(+), 77 deletions(-) diff --git a/pkgs/by-name/dx/dxvk/package.nix b/pkgs/by-name/dx/dxvk/package.nix index d3639215057f..7a8e059ecf78 100644 --- a/pkgs/by-name/dx/dxvk/package.nix +++ b/pkgs/by-name/dx/dxvk/package.nix @@ -1,38 +1,68 @@ -{ lib -, stdenvNoCC -, fetchFromGitHub -, pkgsCross -, stdenv -, bash +{ + lib, + stdenvNoCC, + overrideCC, + fetchFromGitHub, + pkgsCross, + bash, }: -stdenvNoCC.mkDerivation (finalAttrs: +stdenvNoCC.mkDerivation ( + finalAttrs: let - dxvk32 = if stdenv.isDarwin - then pkgsCross.mingw32.dxvk_1.override { enableMoltenVKCompat = true; } - else pkgsCross.mingw32.dxvk_2; - dxvk64 = if stdenv.isDarwin - then pkgsCross.mingwW64.dxvk_1.override { enableMoltenVKCompat = true; } - else pkgsCross.mingwW64.dxvk_2; + useWin32ThreadModel = + stdenv: + overrideCC stdenv ( + stdenv.cc.override (old: { + cc = old.cc.override { + threadsCross = { + model = "win32"; + package = null; + }; + }; + }) + ); + + mingw32Stdenv = useWin32ThreadModel pkgsCross.mingw32.stdenv; + mingwW64Stdenv = useWin32ThreadModel pkgsCross.mingwW64.stdenv; + + dxvk32 = + if stdenvNoCC.isDarwin then + pkgsCross.mingw32.dxvk_1.override { + stdenv = mingw32Stdenv; + enableMoltenVKCompat = true; + } + else + pkgsCross.mingw32.dxvk_2.override { stdenv = mingw32Stdenv; }; + + dxvk64 = + if stdenvNoCC.isDarwin then + pkgsCross.mingwW64.dxvk_1.override { + stdenv = mingwW64Stdenv; + enableMoltenVKCompat = true; + } + else + pkgsCross.mingwW64.dxvk_2.override { stdenv = mingwW64Stdenv; }; in { pname = "dxvk"; inherit (dxvk64) version; - outputs = [ "out" "bin" "lib" ]; + outputs = [ + "out" + "bin" + "lib" + ]; - dontUnpack = true; - dontConfigure = true; - dontBuild = true; + strictDeps = true; - installPhase = '' + buildCommand = '' mkdir -p $out/bin $bin $lib substitute ${./setup_dxvk.sh} $out/bin/setup_dxvk.sh \ --subst-var-by bash ${bash} \ --subst-var-by dxvk32 ${dxvk32} \ --subst-var-by dxvk64 ${dxvk64} \ - --subst-var-by mcfgthreads32 "${pkgsCross.mingw32.windows.mcfgthreads_pre_gcc_13}" \ - --subst-var-by mcfgthreads64 "${pkgsCross.mingwW64.windows.mcfgthreads_pre_gcc_13}" + --subst-var-by version ${finalAttrs.version} chmod a+x $out/bin/setup_dxvk.sh declare -A dxvks=( [x32]=${dxvk32} [x64]=${dxvk64} ) for arch in "''${!dxvks[@]}"; do @@ -41,6 +71,10 @@ stdenvNoCC.mkDerivation (finalAttrs: done ''; + passthru = { inherit dxvk32 dxvk64; }; + + __structuredAttrs = true; + meta = { description = "Setup script for DXVK"; mainProgram = "setup_dxvk.sh"; @@ -48,6 +82,11 @@ stdenvNoCC.mkDerivation (finalAttrs: changelog = "https://github.com/doitsujin/dxvk/releases"; maintainers = [ lib.maintainers.reckenrode ]; license = lib.licenses.zlib; - platforms = [ "x86_64-darwin" "i686-linux" "x86_64-linux" ]; + platforms = [ + "x86_64-darwin" + "i686-linux" + "x86_64-linux" + ]; }; - }) + } +) diff --git a/pkgs/by-name/dx/dxvk/setup_dxvk.sh b/pkgs/by-name/dx/dxvk/setup_dxvk.sh index 4926acd3ba89..27e5d6aa03d5 100644 --- a/pkgs/by-name/dx/dxvk/setup_dxvk.sh +++ b/pkgs/by-name/dx/dxvk/setup_dxvk.sh @@ -6,11 +6,9 @@ set -eu -o pipefail { dxvk32_dir=@dxvk32@/bin dxvk64_dir=@dxvk64@/bin - - mcfgthreads32_dir=@mcfgthreads32@/bin - mcfgthreads64_dir=@mcfgthreads64@/bin } + ## Defaults declare -A dlls=( @@ -18,10 +16,23 @@ declare -A dlls=( [d3d10]="dxvk/d3d10.dll dxvk/d3d10_1.dll dxvk/d3d10core.dll" [d3d11]="dxvk/d3d11.dll" [dxgi]="dxvk/dxgi.dll" +) + +declare -A obsolete_dlls=( [mcfgthreads]="mcfgthreads/mcfgthread-12.dll" ) -declare -A targets=([d3d9]=1 [d3d11]=1 [dxgi]=1 [mcfgthreads]=1) +declare -A targets=([d3d9]=1 [d3d11]=1 [dxgi]=1) + + +# Option variables + +do_cleanup=false +ignore_obsolete=false + +do_symlink=false +do_makeprefix=false + ## Command-line Parsing @@ -46,6 +57,10 @@ usage() { } case "${1:-}" in + cleanup) + do_cleanup=true + shift + ;; uninstall|install) action=$1 shift @@ -61,10 +76,6 @@ case "${1:-}" in ;; esac - -do_symlink=false -do_makeprefix=false - while [ -n "${1:-}" ]; do case "$1" in --with-dxgi) @@ -100,6 +111,10 @@ while [ -n "${1:-}" ]; do usage fi ;; + --ignore-obsolete) + shift + ignore_obsolete=true + ;; -h|--help) usage ;; @@ -111,6 +126,7 @@ while [ -n "${1:-}" ]; do shift done + ## Get information on the Wine environment export WINEPREFIX=${WINEPREFIX:-"$HOME/.wine"} @@ -165,6 +181,7 @@ if [ -z "${win32_sys_path:-}" ] && [ -z "${win64_sys_path:-}" ]; then exit 1 fi + ## Utility functions install_file() { @@ -200,6 +217,13 @@ install_file() { uninstall_file() { srcfile=$1 dstfile=$2 + args=$3 + + if [ "${args}" = "-f" ]; then + rm -v "${dstfile}" + [ -e "${dstfile}.old" ] && rm -v "${dstfile}.old" + return 0 + fi if [ -f "${srcfile}.so" ]; then srcfile="${srcfile}.so" @@ -239,6 +263,26 @@ uninstall_override() { fi } +print_cleanup_message() { + declare -a obsolete_paths=($@) + if ! $ignore_obsolete && [ -n "${obsolete_paths[@]}" ]; then + fold -w $COLUMNS -s <&2 +Obsolete DLLs detected at the specified Wine prefix. These DLLs are no longer needed \ +or managed by the \`setup_dxvk.sh\` script in nixpkgs. You should remove them manually, \ +use the cleanup command, or suppress this message using the \`--ignore-obsolete\` option. +MSG + for obspath in "${obsolete_paths[@]}"; do + if $do_cleanup; then + cleanup_file "$obspath" + else + echo " - ${obspath}" + fi + done + ! $do_cleanup && echo + fi +} + + ## Perform the requested command declare -A paths @@ -260,7 +304,32 @@ for target in "${!targets[@]}"; do done done -for srcpath in "${!paths[@]}"; do - "${action}_file" "$srcpath" "${paths["$srcpath"]}" +declare -A obsolete_paths + +for target in "${!obsolete_dlls[@]}"; do + for dll in ${obsolete_dlls[$target]}; do + dllname=$(basename "$dll") + basedir=$(dirname "$dll") + + if [ -e "${win32_sys_path:-}/$dllname" ]; then + obsolete_paths["${basedir}32_dir/$dllname"]="${win32_sys_path:-}/$dllname" + fi + if [ -e "${win64_sys_path:-}/$dllname" ]; then + obsolete_paths["${basedir}64_dir/$dllname"]="${win64_sys_path:-}/$dllname" + fi + done +done + +if $do_cleanup; then + declare -n action_paths=obsolete_paths + action=uninstall + args=-f +else + declare -n action_paths=paths + print_cleanup_message "${obsolete_paths[@]}" +fi + +for srcpath in "${!action_paths[@]}"; do + "${action}_file" "$srcpath" "${action_paths["$srcpath"]}" "${args:-}" "${action}_override" "$(basename "$srcpath" .dll)" done diff --git a/pkgs/by-name/dx/dxvk_1/package.nix b/pkgs/by-name/dx/dxvk_1/package.nix index a02680d77eec..71223ecea218 100644 --- a/pkgs/by-name/dx/dxvk_1/package.nix +++ b/pkgs/by-name/dx/dxvk_1/package.nix @@ -1,15 +1,16 @@ -{ lib -, stdenv -, fetchFromGitHub -, glslang -, meson -, ninja -, windows -, pkgsBuildHost -, enableMoltenVKCompat ? false +{ + lib, + stdenv, + fetchFromGitHub, + fetchpatch, + glslang, + meson, + ninja, + windows, + enableMoltenVKCompat ? false, }: -stdenv.mkDerivation (finalAttrs: { +stdenv.mkDerivation (finalAttrs: { pname = "dxvk"; version = "1.10.3"; @@ -21,22 +22,35 @@ stdenv.mkDerivation (finalAttrs: { }; # These patches are required when using DXVK with Wine on Darwin. - patches = lib.optionals enableMoltenVKCompat [ - # Patch DXVK to work with MoltenVK even though it doesn’t support some required features. - # Some games work poorly (particularly Unreal Engine 4 games), but others work pretty well. - ./darwin-dxvk-compat.patch - # Use synchronization primitives from the C++ standard library to avoid deadlocks on Darwin. - # See: https://www.reddit.com/r/macgaming/comments/t8liua/comment/hzsuce9/ - ./darwin-thread-primitives.patch - ]; + patches = + [ + # Fixes errors building with GCC 13. + (fetchpatch { + url = "https://github.com/doitsujin/dxvk/commit/1a5afc77b1859e6c7e31b55e11ece899e3b5295a.patch"; + hash = "sha256-tTAsQOMAazgH/6laLNTuG2lki257VUR9EBivnD4vCuY="; + }) + ] + ++ lib.optionals enableMoltenVKCompat [ + # Patch DXVK to work with MoltenVK even though it doesn’t support some required features. + # Some games work poorly (particularly Unreal Engine 4 games), but others work pretty well. + ./darwin-dxvk-compat.patch + # Use synchronization primitives from the C++ standard library to avoid deadlocks on Darwin. + # See: https://www.reddit.com/r/macgaming/comments/t8liua/comment/hzsuce9/ + ./darwin-thread-primitives.patch + ]; - nativeBuildInputs = [ glslang meson ninja ]; + strictDeps = true; + + nativeBuildInputs = [ + glslang + meson + ninja + ]; buildInputs = [ windows.pthreads ]; - mesonFlags = [ - "--buildtype" "release" - "--prefix" "${placeholder "out"}" - ]; + mesonBuildType = "release"; + + __structuredAttrs = true; meta = { description = "A Vulkan-based translation layer for Direct3D 9/10/11"; diff --git a/pkgs/by-name/dx/dxvk_2/package.nix b/pkgs/by-name/dx/dxvk_2/package.nix index 806abea0981c..a42c97a06c02 100644 --- a/pkgs/by-name/dx/dxvk_2/package.nix +++ b/pkgs/by-name/dx/dxvk_2/package.nix @@ -1,18 +1,19 @@ -{ lib -, stdenv -, fetchFromGitHub -, pkgsBuildHost -, glslang -, meson -, ninja -, windows -, spirv-headers -, vulkan-headers -, SDL2 -, glfw -, gitUpdater -, sdl2Support ? true -, glfwSupport ? false +{ + lib, + stdenv, + fetchFromGitHub, + pkgsBuildHost, + glslang, + meson, + ninja, + windows, + spirv-headers, + vulkan-headers, + SDL2, + glfw, + gitUpdater, + sdl2Support ? true, + glfwSupport ? false, }: # SDL2 and GLFW support are mutually exclusive. @@ -21,7 +22,7 @@ assert !sdl2Support || !glfwSupport; let isWindows = stdenv.hostPlatform.uname.system == "Windows"; in -stdenv.mkDerivation (finalAttrs: { +stdenv.mkDerivation (finalAttrs: { pname = "dxvk"; version = "2.3.1"; @@ -38,8 +39,18 @@ stdenv.mkDerivation (finalAttrs: { --replace "/usr/bin/env python3" "${lib.getBin pkgsBuildHost.python3}/bin/python3" ''; - nativeBuildInputs = [ glslang meson ninja ]; - buildInputs = [ spirv-headers vulkan-headers ] + strictDeps = true; + + nativeBuildInputs = [ + glslang + meson + ninja + ]; + buildInputs = + [ + spirv-headers + vulkan-headers + ] ++ lib.optionals (!isWindows && sdl2Support) [ SDL2 ] ++ lib.optionals (!isWindows && glfwSupport) [ glfw ] ++ lib.optionals isWindows [ windows.pthreads ]; @@ -50,15 +61,16 @@ stdenv.mkDerivation (finalAttrs: { mkdir -p include/spirv/include include/vulkan/include ''; - mesonFlags = [ - "--buildtype" "release" - "--prefix" "${placeholder "out"}" - ] ++ lib.optional glfwSupport "-Ddxvk_native_wsi=glfw"; + mesonBuildType = "release"; + + mesonFlags = lib.optionals glfwSupport [ "-Ddxvk_native_wsi=glfw" ]; doCheck = true; passthru.updateScript = gitUpdater { rev-prefix = "v"; }; + __structuredAttrs = true; + meta = { description = "A Vulkan-based translation layer for Direct3D 9/10/11"; homepage = "https://github.com/doitsujin/dxvk";