summary refs log tree commit diff
path: root/pkgs/misc/dxvk/default.nix
blob: b93c46f09100be60143ed86614b9496e390d5f6b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
{ lib
, pkgs
, stdenvNoCC
, fetchFromGitHub
, pkgsCross
}:

stdenvNoCC.mkDerivation (finalAttrs:
  let
    inherit (stdenvNoCC.hostPlatform.uname) system;
    # DXVK needs to be a separate derivation because it’s actually a set of DLLs for Windows that
    # needs to be built with a cross-compiler.
    dxvk32 = pkgsCross.mingw32.callPackage ./dxvk.nix {
      inherit (finalAttrs) src version dxvkPatches;
    };
    dxvk64 = pkgsCross.mingwW64.callPackage ./dxvk.nix {
      inherit (finalAttrs) src version dxvkPatches;
    };

    # Split out by platform to make maintenance easy in case supported versions on Darwin and other
    # platforms diverge (due to the need for Darwin-specific patches that would fail to apply).
    # Should that happen, set `darwin` to the last working `rev` and `hash`.
    srcs = rec {
      darwin = {
        rev = "v${finalAttrs.version}";
        hash = "sha256-T93ZylxzJGprrP+j6axZwl2d3hJowMCUOKNjIyNzkmE=";
        version = "1.10.3";
      };
      default = {
        rev = "v${finalAttrs.version}";
        hash = "sha256-mboVLdPgZMzmqyeF0jAloEz6xqfIDiY/X98e7l2KZnw=";
        version = "2.0";
      };
    };
  in
  {
    name = "dxvk";
    inherit (srcs."${system}" or srcs.default) version;

    src = fetchFromGitHub {
      owner = "doitsujin";
      repo = "dxvk";
      inherit (srcs."${system}" or srcs.default) rev hash;
    };

    # Override this to patch DXVK itself (rather than the setup script).
    dxvkPatches = lib.optionals stdenvNoCC.isDarwin [
      # 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
    ];

    outputs = [ "out" "bin" "lib" ];

    # Also copy `mcfgthread-12.dll` due to DXVK’s being built in a MinGW cross environment.
    patches = [ ./mcfgthread.patch ];

    dontConfigure = true;
    dontBuild = true;

    installPhase = ''
      mkdir -p $out/bin $bin $lib
      # Replace both basedir forms to support both DXVK 2.0 and older versions.
      substitute setup_dxvk.sh $out/bin/setup_dxvk.sh \
        --subst-var-by mcfgthreads32 "${pkgsCross.mingw32.windows.mcfgthreads}" \
        --subst-var-by mcfgthreads64 "${pkgsCross.mingwW64.windows.mcfgthreads}" \
        --replace 'basedir=$(dirname "$(readlink -f $0)")' "basedir=$bin" \
        --replace 'basedir="$(dirname "$(readlink -f "$0")")"' "basedir=$bin"
      chmod a+x $out/bin/setup_dxvk.sh
      declare -A dxvks=( [x32]=${dxvk32} [x64]=${dxvk64} )
      for arch in "''${!dxvks[@]}"; do
        ln -s "''${dxvks[$arch]}/bin" $bin/$arch
        ln -s "''${dxvks[$arch]}/lib" $lib/$arch
      done
    '';

    meta = {
      description = "A Vulkan-based translation layer for Direct3D 9/10/11";
      homepage = "https://github.com/doitsujin/dxvk";
      changelog = "https://github.com/doitsujin/dxvk/releases";
      maintainers = [ lib.maintainers.reckenrode ];
      license = lib.licenses.zlib;
      platforms = [ "x86_64-darwin" "i686-linux" "x86_64-linux" ];
    };
  })