diff options
author | Sandro <sandro.jaeckel@gmail.com> | 2022-03-27 17:00:33 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-27 17:00:33 +0200 |
commit | 1bf32e43deaf8a89aac50fb9e24667714c20bc9d (patch) | |
tree | 5589fb3a9f5da8f9b7921c3028f14dc3b90c8d48 | |
parent | 05fc9a6c90aada4938fdbfd3e25d8434c307706b (diff) | |
parent | 2f4eedc4017a82a88b3dbc4d4b98fb1b1dcf299c (diff) | |
download | nixlib-1bf32e43deaf8a89aac50fb9e24667714c20bc9d.tar nixlib-1bf32e43deaf8a89aac50fb9e24667714c20bc9d.tar.gz nixlib-1bf32e43deaf8a89aac50fb9e24667714c20bc9d.tar.bz2 nixlib-1bf32e43deaf8a89aac50fb9e24667714c20bc9d.tar.lz nixlib-1bf32e43deaf8a89aac50fb9e24667714c20bc9d.tar.xz nixlib-1bf32e43deaf8a89aac50fb9e24667714c20bc9d.tar.zst nixlib-1bf32e43deaf8a89aac50fb9e24667714c20bc9d.zip |
Merge pull request #163474 from reckenrode/dxvk-refactor
-rw-r--r-- | pkgs/misc/dxvk/darwin-thread-primitives.patch | 186 | ||||
-rw-r--r-- | pkgs/misc/dxvk/default.nix | 43 | ||||
-rw-r--r-- | pkgs/misc/dxvk/dxvk.nix | 12 | ||||
-rw-r--r-- | pkgs/os-specific/darwin/moltenvk/default.nix | 4 | ||||
-rw-r--r-- | pkgs/os-specific/darwin/moltenvk/dxvk-moltenvk-compat.patch (renamed from pkgs/misc/dxvk/darwin-moltenvk-compat.patch) | 0 |
5 files changed, 222 insertions, 23 deletions
diff --git a/pkgs/misc/dxvk/darwin-thread-primitives.patch b/pkgs/misc/dxvk/darwin-thread-primitives.patch new file mode 100644 index 000000000000..c008099407c5 --- /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 61e2d78b45c0..7c466b44ae6b 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 40b674df9225..2eb4f30df2bc 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"; diff --git a/pkgs/os-specific/darwin/moltenvk/default.nix b/pkgs/os-specific/darwin/moltenvk/default.nix index ba8bc605e8b4..dc7f3f58fd3a 100644 --- a/pkgs/os-specific/darwin/moltenvk/default.nix +++ b/pkgs/os-specific/darwin/moltenvk/default.nix @@ -43,6 +43,10 @@ stdenvNoCC.mkDerivation rec { # MoltenVK requires specific versions of its dependencies. # Pin them here except for cereal, which is four years old and has several CVEs. passthru = { + # The patch required to support DXVK may different from version to version. This should never + # be used except with DXVK, so there’s no package for it. To emphasize that this patch should + # never be used except with DXVK, `dxvk` provides a function for applying this patch. + dxvkPatch = ./dxvk-moltenvk-compat.patch; glslang = (glslang.overrideAttrs (old: { src = fetchFromGitHub { owner = "KhronosGroup"; diff --git a/pkgs/misc/dxvk/darwin-moltenvk-compat.patch b/pkgs/os-specific/darwin/moltenvk/dxvk-moltenvk-compat.patch index 7d16fdf70331..7d16fdf70331 100644 --- a/pkgs/misc/dxvk/darwin-moltenvk-compat.patch +++ b/pkgs/os-specific/darwin/moltenvk/dxvk-moltenvk-compat.patch |