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
, 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"
];
};
})
}
)

View file

@ -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 <<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
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

View file

@ -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 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
];
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 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 ];
mesonFlags = [
"--buildtype" "release"
"--prefix" "${placeholder "out"}"
];
mesonBuildType = "release";
__structuredAttrs = true;
meta = {
description = "A Vulkan-based translation layer for Direct3D 9/10/11";

View file

@ -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";