about summary refs log tree commit diff
path: root/pkgs/misc
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2022-03-27 18:01:05 +0000
committerGitHub <noreply@github.com>2022-03-27 18:01:05 +0000
commite3d20dfaa59f5fde6b277943b7bc080390627bfa (patch)
tree404869fa5ebdd1ad8859cafd378c8ef3221707c0 /pkgs/misc
parent086c62dd5eab696e889d6fb87c3cc0d10ca00762 (diff)
parent5f6a4fb8a7974aacdacb0a11566b3a35376cca49 (diff)
Merge master into staging-next
Diffstat (limited to 'pkgs/misc')
-rw-r--r--pkgs/misc/dxvk/darwin-moltenvk-compat.patch59
-rw-r--r--pkgs/misc/dxvk/darwin-thread-primitives.patch186
-rw-r--r--pkgs/misc/dxvk/default.nix43
-rw-r--r--pkgs/misc/dxvk/dxvk.nix12
4 files changed, 218 insertions, 82 deletions
diff --git a/pkgs/misc/dxvk/darwin-moltenvk-compat.patch b/pkgs/misc/dxvk/darwin-moltenvk-compat.patch
deleted file mode 100644
index 7d16fdf703318..0000000000000
--- a/pkgs/misc/dxvk/darwin-moltenvk-compat.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-Source: https://github.com/Gcenx/MoltenVK/commit/1f268bd45f6c928784d7cb90dedce382895f10ae
-
-Fake extensions for DXVK;
-- _features.geometryShader
-- _features.tessellationShader
-- _features.shaderCullDistance
-
-Enabled defaults;
-- MVK_ALLOW_METAL_FENCES=1
-- MVK_CONFIG_RESUME_LOST_DEVICE=1
----
- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm  | 3 +++
- MoltenVK/MoltenVK/Utility/MVKEnvironment.h | 4 ++--
- 2 files changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
-index bc6d19df..e1959c6e 100644
---- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
-+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
-@@ -1656,6 +1656,8 @@
-     _features.robustBufferAccess = true;  // XXX Required by Vulkan spec
-     _features.fullDrawIndexUint32 = true;
-     _features.independentBlend = true;
-+    _features.geometryShader = true;  // XXX Required by DXVK for D3D10
-+    _features.tessellationShader = true;  // XXX Required by DXVK for D3D11
-     _features.sampleRateShading = true;
-     _features.depthBiasClamp = true;
-     _features.fillModeNonSolid = true;
-@@ -1669,6 +1671,7 @@
-     _features.shaderUniformBufferArrayDynamicIndexing = true;
-     _features.shaderStorageBufferArrayDynamicIndexing = true;
-     _features.shaderClipDistance = true;
-+    _features.shaderCullDistance = true;  // XXX Required by DXVK for 10level9
-     _features.shaderInt16 = true;
-     _features.multiDrawIndirect = true;
-     _features.inheritedQueries = true;
-diff --git a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h
-index 81d0defc..80c414d3 100644
---- a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h
-+++ b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h
-@@ -240,7 +240,7 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig);
- #   define MVK_ALLOW_METAL_EVENTS    1
- #endif
- #ifndef MVK_ALLOW_METAL_FENCES
--#   define MVK_ALLOW_METAL_FENCES    0
-+#   define MVK_ALLOW_METAL_FENCES    1 // XXX Required by DXVK for Apple/NVidia GPUs (better FPS than CPU Emulation)
- #endif
- 
- /** Substitute Metal 2D textures for Vulkan 1D images. Enabled by default. */
-@@ -275,7 +275,7 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig);
- 
- /** Resume MVKDevice VK_ERROR_DEVICE_LOST errors that do not cause MVKPhysicalDevice errors. Disabled by default. */
- #ifndef MVK_CONFIG_RESUME_LOST_DEVICE
--#   define MVK_CONFIG_RESUME_LOST_DEVICE    0
-+#   define MVK_CONFIG_RESUME_LOST_DEVICE    1
- #endif
- 
- /** Support Metal argument buffers. Disabled by default. */
- 
\ No newline at end of file
diff --git a/pkgs/misc/dxvk/darwin-thread-primitives.patch b/pkgs/misc/dxvk/darwin-thread-primitives.patch
new file mode 100644
index 0000000000000..c008099407c57
--- /dev/null
+++ b/pkgs/misc/dxvk/darwin-thread-primitives.patch
@@ -0,0 +1,186 @@
+diff --git a/src/util/thread.h b/src/util/thread.h
+index 28aeca8a..db5c9913 100644
+--- a/src/util/thread.h
++++ b/src/util/thread.h
+@@ -149,178 +149,8 @@ namespace dxvk {
+     }
+   }
+ 
+-
+-  /**
+-   * \brief SRW-based mutex implementation
+-   *
+-   * Drop-in replacement for \c std::mutex that uses Win32
+-   * SRW locks, which are implemented with \c futex in wine.
+-   */
+-  class mutex {
+-
+-  public:
+-
+-    using native_handle_type = PSRWLOCK;
+-
+-    mutex() { }
+-
+-    mutex(const mutex&) = delete;
+-    mutex& operator = (const mutex&) = delete;
+-
+-    void lock() {
+-      AcquireSRWLockExclusive(&m_lock);
+-    }
+-
+-    void unlock() {
+-      ReleaseSRWLockExclusive(&m_lock);
+-    }
+-
+-    bool try_lock() {
+-      return TryAcquireSRWLockExclusive(&m_lock);
+-    }
+-
+-    native_handle_type native_handle() {
+-      return &m_lock;
+-    }
+-
+-  private:
+-
+-    SRWLOCK m_lock = SRWLOCK_INIT;
+-
+-  };
+-
+-
+-  /**
+-   * \brief Recursive mutex implementation
+-   *
+-   * Drop-in replacement for \c std::recursive_mutex that
+-   * uses Win32 critical sections.
+-   */
+-  class recursive_mutex {
+-
+-  public:
+-
+-    using native_handle_type = PCRITICAL_SECTION;
+-
+-    recursive_mutex() {
+-      InitializeCriticalSection(&m_lock);
+-    }
+-
+-    ~recursive_mutex() {
+-      DeleteCriticalSection(&m_lock);
+-    }
+-
+-    recursive_mutex(const recursive_mutex&) = delete;
+-    recursive_mutex& operator = (const recursive_mutex&) = delete;
+-
+-    void lock() {
+-      EnterCriticalSection(&m_lock);
+-    }
+-
+-    void unlock() {
+-      LeaveCriticalSection(&m_lock);
+-    }
+-
+-    bool try_lock() {
+-      return TryEnterCriticalSection(&m_lock);
+-    }
+-
+-    native_handle_type native_handle() {
+-      return &m_lock;
+-    }
+-
+-  private:
+-
+-    CRITICAL_SECTION m_lock;
+-
+-  };
+-
+-
+-  /**
+-   * \brief SRW-based condition variable implementation
+-   *
+-   * Drop-in replacement for \c std::condition_variable that
+-   * uses Win32 condition variables on SRW locks.
+-   */
+-  class condition_variable {
+-
+-  public:
+-
+-    using native_handle_type = PCONDITION_VARIABLE;
+-
+-    condition_variable() {
+-      InitializeConditionVariable(&m_cond);
+-    }
+-
+-    condition_variable(condition_variable&) = delete;
+-
+-    condition_variable& operator = (condition_variable&) = delete;
+-
+-    void notify_one() {
+-      WakeConditionVariable(&m_cond);
+-    }
+-
+-    void notify_all() {
+-      WakeAllConditionVariable(&m_cond);
+-    }
+-
+-    void wait(std::unique_lock<dxvk::mutex>& lock) {
+-      auto srw = lock.mutex()->native_handle();
+-      SleepConditionVariableSRW(&m_cond, srw, INFINITE, 0);
+-    }
+-
+-    template<typename Predicate>
+-    void wait(std::unique_lock<dxvk::mutex>& lock, Predicate pred) {
+-      while (!pred())
+-        wait(lock);
+-    }
+-
+-    template<typename Clock, typename Duration>
+-    std::cv_status wait_until(std::unique_lock<dxvk::mutex>& lock, const std::chrono::time_point<Clock, Duration>& time) {
+-      auto now = Clock::now();
+-
+-      return (now < time)
+-        ? wait_for(lock, now - time)
+-        : std::cv_status::timeout;
+-    }
+-
+-    template<typename Clock, typename Duration, typename Predicate>
+-    bool wait_until(std::unique_lock<dxvk::mutex>& lock, const std::chrono::time_point<Clock, Duration>& time, Predicate pred) {
+-      if (pred())
+-        return true;
+-
+-      auto now = Clock::now();
+-      return now < time && wait_for(lock, now - time, pred);
+-    }
+-
+-    template<typename Rep, typename Period>
+-    std::cv_status wait_for(std::unique_lock<dxvk::mutex>& lock, const std::chrono::duration<Rep, Period>& timeout) {
+-      auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(timeout);
+-      auto srw = lock.mutex()->native_handle();
+-
+-      return SleepConditionVariableSRW(&m_cond, srw, ms.count(), 0)
+-        ? std::cv_status::no_timeout
+-        : std::cv_status::timeout;
+-    }
+-
+-    template<typename Rep, typename Period, typename Predicate>
+-    bool wait_for(std::unique_lock<dxvk::mutex>& lock, const std::chrono::duration<Rep, Period>& timeout, Predicate pred) {
+-      bool result = pred();
+-
+-      if (!result && wait_for(lock, timeout) == std::cv_status::no_timeout)
+-        result = pred();
+-
+-      return result;
+-    }
+-
+-    native_handle_type native_handle() {
+-      return &m_cond;
+-    }
+-
+-  private:
+-
+-    CONDITION_VARIABLE m_cond;
+-
+-  };
++  using mutex = std::mutex;
++  using recursive_mutex = std::recursive_mutex;
++  using condition_variable = std::condition_variable;
+ 
+ }
diff --git a/pkgs/misc/dxvk/default.nix b/pkgs/misc/dxvk/default.nix
index 61e2d78b45c0d..7c466b44ae6b3 100644
--- a/pkgs/misc/dxvk/default.nix
+++ b/pkgs/misc/dxvk/default.nix
@@ -1,33 +1,52 @@
 { lib
 , pkgs
-, stdenv
+, hostPlatform
+, stdenvNoCC
 , fetchFromGitHub
 , pkgsCross
 }:
 
 let
+  inherit (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 (self) src version dxvkPatches; };
   dxvk64 = pkgsCross.mingwW64.callPackage ./dxvk.nix { inherit (self) 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 = { inherit (default) rev hash version; };
+    default = {
+      rev = "v${self.version}";
+      hash = "sha256-+6PkrkamSvhCaGj2tq+RXri/yQ7vs0cAqgdRAFtU8UA=";
+      version = "1.10.1";
+    };
+  };
+
   # Use the self pattern to support overriding `src` and `version` via `overrideAttrs`. A recursive
   # attrset wouldn’t work.
-  self = stdenv.mkDerivation {
+  self = stdenvNoCC.mkDerivation {
     name = "dxvk";
-    version = "1.10";
+    inherit (srcs."${system}" or srcs.default) version;
 
     src = fetchFromGitHub {
       owner = "doitsujin";
       repo = "dxvk";
-      rev = "v${self.version}";
-      hash = "sha256-/zH6vER/6s/d+Tt181UJOa97sqdkJyKGw6E36+1owzQ=";
+      inherit (srcs."${system}" or srcs.default) rev hash;
     };
 
-    # Patch DXVK to work with MoltenVK even though it doesn’t support some required features.
-    # Some games will work poorly (particularly Unreal Engine 4 games), but others work pretty well.
     # Override this to patch DXVK itself (rather than the setup script).
-    dxvkPatches = lib.optional stdenv.isDarwin ./darwin-dxvk-compat.patch;
+    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" ];
 
@@ -53,6 +72,7 @@ let
 
     # DXVK with MoltenVK requires a patched MoltenVK in addition to its own patches. Provide a
     # convenience function to handle the necessary patching.
+    #
     # Usage:
     # let
     #   patchedMoltenVK = dxvk.patchMoltenVK darwin.moltenvk;
@@ -61,9 +81,10 @@ let
     passthru.patchMoltenVK = moltenvk:
       moltenvk.overrideAttrs (old: {
         patches = old.patches or [ ] ++ [
-          # Lie to DXVK about certain features that DXVK expects to be available and set defaults
-          # for better performance/compatability on certain hardware.
-          ./darwin-moltenvk-compat.patch
+          # Apply MoltenVK’s DXVK compatability patch. This is needed to fake support for certain
+          # extensions. There is no package for a patched MoltenVK to avoid any confusion by users
+          # whether they should use it. Except with DXVK, the answer is always no.
+          old.passthru.dxvkPatch
         ];
       });
 
diff --git a/pkgs/misc/dxvk/dxvk.nix b/pkgs/misc/dxvk/dxvk.nix
index 40b674df9225d..2eb4f30df2bc3 100644
--- a/pkgs/misc/dxvk/dxvk.nix
+++ b/pkgs/misc/dxvk/dxvk.nix
@@ -19,18 +19,6 @@ stdenv.mkDerivation {
 
   patches = dxvkPatches;
 
-  # Replace use of DXVK’s threading classes with the ones from the C++ standard library, which uses
-  # mcfgthreads in nixpkgs.
-  postPatch = ''
-    for class in mutex recursive_mutex condition_variable; do
-      for file in $(grep -rl dxvk::$class *); do
-        if [ "$(basename "$file")" != "thread.h" ]; then
-          substituteInPlace "$file" --replace dxvk::$class std::$class
-        fi
-      done
-    done
-  '';
-
   mesonFlags =
     let
       arch = if stdenv.is32bit then "32" else "64";