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.
This commit is contained in:
Randy Eckenrode 2024-03-25 14:33:28 -04:00
parent e2a78e866f
commit 59d5307cae
No known key found for this signature in database
GPG key ID: 64C1CD4EC2A600D9
4 changed files with 211 additions and 77 deletions

View file

@ -1,38 +1,68 @@
{ lib {
, stdenvNoCC lib,
, fetchFromGitHub stdenvNoCC,
, pkgsCross overrideCC,
, stdenv fetchFromGitHub,
, bash pkgsCross,
bash,
}: }:
stdenvNoCC.mkDerivation (finalAttrs: stdenvNoCC.mkDerivation (
finalAttrs:
let let
dxvk32 = if stdenv.isDarwin useWin32ThreadModel =
then pkgsCross.mingw32.dxvk_1.override { enableMoltenVKCompat = true; } stdenv:
else pkgsCross.mingw32.dxvk_2; overrideCC stdenv (
dxvk64 = if stdenv.isDarwin stdenv.cc.override (old: {
then pkgsCross.mingwW64.dxvk_1.override { enableMoltenVKCompat = true; } cc = old.cc.override {
else pkgsCross.mingwW64.dxvk_2; 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 in
{ {
pname = "dxvk"; pname = "dxvk";
inherit (dxvk64) version; inherit (dxvk64) version;
outputs = [ "out" "bin" "lib" ]; outputs = [
"out"
"bin"
"lib"
];
dontUnpack = true; strictDeps = true;
dontConfigure = true;
dontBuild = true;
installPhase = '' buildCommand = ''
mkdir -p $out/bin $bin $lib mkdir -p $out/bin $bin $lib
substitute ${./setup_dxvk.sh} $out/bin/setup_dxvk.sh \ substitute ${./setup_dxvk.sh} $out/bin/setup_dxvk.sh \
--subst-var-by bash ${bash} \ --subst-var-by bash ${bash} \
--subst-var-by dxvk32 ${dxvk32} \ --subst-var-by dxvk32 ${dxvk32} \
--subst-var-by dxvk64 ${dxvk64} \ --subst-var-by dxvk64 ${dxvk64} \
--subst-var-by mcfgthreads32 "${pkgsCross.mingw32.windows.mcfgthreads_pre_gcc_13}" \ --subst-var-by version ${finalAttrs.version}
--subst-var-by mcfgthreads64 "${pkgsCross.mingwW64.windows.mcfgthreads_pre_gcc_13}"
chmod a+x $out/bin/setup_dxvk.sh chmod a+x $out/bin/setup_dxvk.sh
declare -A dxvks=( [x32]=${dxvk32} [x64]=${dxvk64} ) declare -A dxvks=( [x32]=${dxvk32} [x64]=${dxvk64} )
for arch in "''${!dxvks[@]}"; do for arch in "''${!dxvks[@]}"; do
@ -41,6 +71,10 @@ stdenvNoCC.mkDerivation (finalAttrs:
done done
''; '';
passthru = { inherit dxvk32 dxvk64; };
__structuredAttrs = true;
meta = { meta = {
description = "Setup script for DXVK"; description = "Setup script for DXVK";
mainProgram = "setup_dxvk.sh"; mainProgram = "setup_dxvk.sh";
@ -48,6 +82,11 @@ stdenvNoCC.mkDerivation (finalAttrs:
changelog = "https://github.com/doitsujin/dxvk/releases"; changelog = "https://github.com/doitsujin/dxvk/releases";
maintainers = [ lib.maintainers.reckenrode ]; maintainers = [ lib.maintainers.reckenrode ];
license = lib.licenses.zlib; license = lib.licenses.zlib;
platforms = [ "x86_64-darwin" "i686-linux" "x86_64-linux" ]; platforms = [
"x86_64-darwin"
"i686-linux"
"x86_64-linux"
];
}; };
}) }
)

View file

@ -6,11 +6,9 @@ set -eu -o pipefail
{ {
dxvk32_dir=@dxvk32@/bin dxvk32_dir=@dxvk32@/bin
dxvk64_dir=@dxvk64@/bin dxvk64_dir=@dxvk64@/bin
mcfgthreads32_dir=@mcfgthreads32@/bin
mcfgthreads64_dir=@mcfgthreads64@/bin
} }
## Defaults ## Defaults
declare -A dlls=( declare -A dlls=(
@ -18,10 +16,23 @@ declare -A dlls=(
[d3d10]="dxvk/d3d10.dll dxvk/d3d10_1.dll dxvk/d3d10core.dll" [d3d10]="dxvk/d3d10.dll dxvk/d3d10_1.dll dxvk/d3d10core.dll"
[d3d11]="dxvk/d3d11.dll" [d3d11]="dxvk/d3d11.dll"
[dxgi]="dxvk/dxgi.dll" [dxgi]="dxvk/dxgi.dll"
)
declare -A obsolete_dlls=(
[mcfgthreads]="mcfgthreads/mcfgthread-12.dll" [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 ## Command-line Parsing
@ -46,6 +57,10 @@ usage() {
} }
case "${1:-}" in case "${1:-}" in
cleanup)
do_cleanup=true
shift
;;
uninstall|install) uninstall|install)
action=$1 action=$1
shift shift
@ -61,10 +76,6 @@ case "${1:-}" in
;; ;;
esac esac
do_symlink=false
do_makeprefix=false
while [ -n "${1:-}" ]; do while [ -n "${1:-}" ]; do
case "$1" in case "$1" in
--with-dxgi) --with-dxgi)
@ -100,6 +111,10 @@ while [ -n "${1:-}" ]; do
usage usage
fi fi
;; ;;
--ignore-obsolete)
shift
ignore_obsolete=true
;;
-h|--help) -h|--help)
usage usage
;; ;;
@ -111,6 +126,7 @@ while [ -n "${1:-}" ]; do
shift shift
done done
## Get information on the Wine environment ## Get information on the Wine environment
export WINEPREFIX=${WINEPREFIX:-"$HOME/.wine"} export WINEPREFIX=${WINEPREFIX:-"$HOME/.wine"}
@ -165,6 +181,7 @@ if [ -z "${win32_sys_path:-}" ] && [ -z "${win64_sys_path:-}" ]; then
exit 1 exit 1
fi fi
## Utility functions ## Utility functions
install_file() { install_file() {
@ -200,6 +217,13 @@ install_file() {
uninstall_file() { uninstall_file() {
srcfile=$1 srcfile=$1
dstfile=$2 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 if [ -f "${srcfile}.so" ]; then
srcfile="${srcfile}.so" srcfile="${srcfile}.so"
@ -239,6 +263,26 @@ uninstall_override() {
fi fi
} }
print_cleanup_message() {
declare -a obsolete_paths=($@)
if ! $ignore_obsolete && [ -n "${obsolete_paths[@]}" ]; then
fold -w $COLUMNS -s <<MSG >&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 ## Perform the requested command
declare -A paths declare -A paths
@ -260,7 +304,32 @@ for target in "${!targets[@]}"; do
done done
done done
for srcpath in "${!paths[@]}"; do declare -A obsolete_paths
"${action}_file" "$srcpath" "${paths["$srcpath"]}"
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)" "${action}_override" "$(basename "$srcpath" .dll)"
done done

View file

@ -1,15 +1,16 @@
{ lib {
, stdenv lib,
, fetchFromGitHub stdenv,
, glslang fetchFromGitHub,
, meson fetchpatch,
, ninja glslang,
, windows meson,
, pkgsBuildHost ninja,
, enableMoltenVKCompat ? false windows,
enableMoltenVKCompat ? false,
}: }:
stdenv.mkDerivation (finalAttrs: { stdenv.mkDerivation (finalAttrs: {
pname = "dxvk"; pname = "dxvk";
version = "1.10.3"; version = "1.10.3";
@ -21,22 +22,35 @@ stdenv.mkDerivation (finalAttrs: {
}; };
# These patches are required when using DXVK with Wine on Darwin. # These patches are required when using DXVK with Wine on Darwin.
patches = lib.optionals enableMoltenVKCompat [ patches =
# Patch DXVK to work with MoltenVK even though it doesnt support some required features. [
# Some games work poorly (particularly Unreal Engine 4 games), but others work pretty well. # Fixes errors building with GCC 13.
./darwin-dxvk-compat.patch (fetchpatch {
# Use synchronization primitives from the C++ standard library to avoid deadlocks on Darwin. url = "https://github.com/doitsujin/dxvk/commit/1a5afc77b1859e6c7e31b55e11ece899e3b5295a.patch";
# See: https://www.reddit.com/r/macgaming/comments/t8liua/comment/hzsuce9/ hash = "sha256-tTAsQOMAazgH/6laLNTuG2lki257VUR9EBivnD4vCuY=";
./darwin-thread-primitives.patch })
]; ]
++ lib.optionals enableMoltenVKCompat [
# Patch DXVK to work with MoltenVK even though it doesnt 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 ]; buildInputs = [ windows.pthreads ];
mesonFlags = [ mesonBuildType = "release";
"--buildtype" "release"
"--prefix" "${placeholder "out"}" __structuredAttrs = true;
];
meta = { meta = {
description = "A Vulkan-based translation layer for Direct3D 9/10/11"; description = "A Vulkan-based translation layer for Direct3D 9/10/11";

View file

@ -1,18 +1,19 @@
{ lib {
, stdenv lib,
, fetchFromGitHub stdenv,
, pkgsBuildHost fetchFromGitHub,
, glslang pkgsBuildHost,
, meson glslang,
, ninja meson,
, windows ninja,
, spirv-headers windows,
, vulkan-headers spirv-headers,
, SDL2 vulkan-headers,
, glfw SDL2,
, gitUpdater glfw,
, sdl2Support ? true gitUpdater,
, glfwSupport ? false sdl2Support ? true,
glfwSupport ? false,
}: }:
# SDL2 and GLFW support are mutually exclusive. # SDL2 and GLFW support are mutually exclusive.
@ -21,7 +22,7 @@ assert !sdl2Support || !glfwSupport;
let let
isWindows = stdenv.hostPlatform.uname.system == "Windows"; isWindows = stdenv.hostPlatform.uname.system == "Windows";
in in
stdenv.mkDerivation (finalAttrs: { stdenv.mkDerivation (finalAttrs: {
pname = "dxvk"; pname = "dxvk";
version = "2.3.1"; version = "2.3.1";
@ -38,8 +39,18 @@ stdenv.mkDerivation (finalAttrs: {
--replace "/usr/bin/env python3" "${lib.getBin pkgsBuildHost.python3}/bin/python3" --replace "/usr/bin/env python3" "${lib.getBin pkgsBuildHost.python3}/bin/python3"
''; '';
nativeBuildInputs = [ glslang meson ninja ]; strictDeps = true;
buildInputs = [ spirv-headers vulkan-headers ]
nativeBuildInputs = [
glslang
meson
ninja
];
buildInputs =
[
spirv-headers
vulkan-headers
]
++ lib.optionals (!isWindows && sdl2Support) [ SDL2 ] ++ lib.optionals (!isWindows && sdl2Support) [ SDL2 ]
++ lib.optionals (!isWindows && glfwSupport) [ glfw ] ++ lib.optionals (!isWindows && glfwSupport) [ glfw ]
++ lib.optionals isWindows [ windows.pthreads ]; ++ lib.optionals isWindows [ windows.pthreads ];
@ -50,15 +61,16 @@ stdenv.mkDerivation (finalAttrs: {
mkdir -p include/spirv/include include/vulkan/include mkdir -p include/spirv/include include/vulkan/include
''; '';
mesonFlags = [ mesonBuildType = "release";
"--buildtype" "release"
"--prefix" "${placeholder "out"}" mesonFlags = lib.optionals glfwSupport [ "-Ddxvk_native_wsi=glfw" ];
] ++ lib.optional glfwSupport "-Ddxvk_native_wsi=glfw";
doCheck = true; doCheck = true;
passthru.updateScript = gitUpdater { rev-prefix = "v"; }; passthru.updateScript = gitUpdater { rev-prefix = "v"; };
__structuredAttrs = true;
meta = { meta = {
description = "A Vulkan-based translation layer for Direct3D 9/10/11"; description = "A Vulkan-based translation layer for Direct3D 9/10/11";
homepage = "https://github.com/doitsujin/dxvk"; homepage = "https://github.com/doitsujin/dxvk";