diff options
Diffstat (limited to 'nixpkgs/pkgs/by-name/dx')
-rw-r--r-- | nixpkgs/pkgs/by-name/dx/dxvk/package.nix | 52 | ||||
-rw-r--r-- | nixpkgs/pkgs/by-name/dx/dxvk/setup_dxvk.sh | 266 | ||||
-rw-r--r-- | nixpkgs/pkgs/by-name/dx/dxvk_1/darwin-dxvk-compat.patch | 48 | ||||
-rw-r--r-- | nixpkgs/pkgs/by-name/dx/dxvk_1/darwin-thread-primitives.patch | 186 | ||||
-rw-r--r-- | nixpkgs/pkgs/by-name/dx/dxvk_1/package.nix | 57 | ||||
-rw-r--r-- | nixpkgs/pkgs/by-name/dx/dxvk_2/package.nix | 77 |
6 files changed, 686 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/by-name/dx/dxvk/package.nix b/nixpkgs/pkgs/by-name/dx/dxvk/package.nix new file mode 100644 index 000000000000..88b7e5b104fb --- /dev/null +++ b/nixpkgs/pkgs/by-name/dx/dxvk/package.nix @@ -0,0 +1,52 @@ +{ lib +, stdenvNoCC +, fetchFromGitHub +, pkgsCross +, stdenv +, bash +}: + +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; + in + { + pname = "dxvk"; + inherit (dxvk64) version; + + outputs = [ "out" "bin" "lib" ]; + + dontUnpack = true; + dontConfigure = true; + dontBuild = true; + + installPhase = '' + 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}" + 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 = "Setup script for DXVK"; + 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" ]; + }; + }) diff --git a/nixpkgs/pkgs/by-name/dx/dxvk/setup_dxvk.sh b/nixpkgs/pkgs/by-name/dx/dxvk/setup_dxvk.sh new file mode 100644 index 000000000000..4926acd3ba89 --- /dev/null +++ b/nixpkgs/pkgs/by-name/dx/dxvk/setup_dxvk.sh @@ -0,0 +1,266 @@ +#!@bash@/bin/bash -e + +set -eu -o pipefail + +# shellcheck disable=SC2034 +{ + dxvk32_dir=@dxvk32@/bin + dxvk64_dir=@dxvk64@/bin + + mcfgthreads32_dir=@mcfgthreads32@/bin + mcfgthreads64_dir=@mcfgthreads64@/bin +} + +## Defaults + +declare -A dlls=( + [d3d9]="dxvk/d3d9.dll" + [d3d10]="dxvk/d3d10.dll dxvk/d3d10_1.dll dxvk/d3d10core.dll" + [d3d11]="dxvk/d3d11.dll" + [dxgi]="dxvk/dxgi.dll" + [mcfgthreads]="mcfgthreads/mcfgthread-12.dll" +) + +declare -A targets=([d3d9]=1 [d3d11]=1 [dxgi]=1 [mcfgthreads]=1) + +## Command-line Parsing + +usage() { + echo "DXVK @version@" + echo "Set up Wine prefix with DXVK DLLs" + echo + echo "USAGE" + echo " $0 [install|uninstall] [OPTIONS]" + echo + echo "COMMANDS" + echo " install Copy the DXVK DLLs into the prefix" + echo " uninstall Restore the backed up Wine DLLs in the prefix" + echo + echo "OPTIONS" + echo " --with(out)-dxgi Copy DXVK DXGI DLL into prefix (default: with DXGI)" + echo " --with(out)-d3d10 Copy D3D10 DLLs into prefix (default: without D3D10)" + echo " -s, --symlink Symlink instead of copy" + echo " -f, --force Create a Wine prefix even if it does not exist" + echo " -p, --prefix <PREFIX> Wine prefix to manage (default: \$WINEPREFIX)" + exit 1 +} + +case "${1:-}" in + uninstall|install) + action=$1 + shift + ;; + -h|--help) + usage + ;; + *) + if [ -n "${1:-}" ]; then + echo "Unrecognized command: $1" + fi + usage + ;; +esac + + +do_symlink=false +do_makeprefix=false + +while [ -n "${1:-}" ]; do + case "$1" in + --with-dxgi) + targets[dxgi]=1 + ;; + --without-dxgi) + unset "targets[dxgi]" + ;; + --with-d3d10) + targets[d3d10]=1 + ;; + --without-d3d10) + unset "targets[d3d10]" + ;; + -s|--symlink) + do_symlink=true + ;; + --no-symlink) + do_symlink=false + ;; + -f|--force) + do_makeprefix=true + ;; + --no-force) + do_makeprefix=false + ;; + -p|--prefix) + shift + if [ -n "${1:-}" ]; then + WINEPREFIX=$1 + else + echo "Required PREFIX missing" + usage + fi + ;; + -h|--help) + usage + ;; + *) + echo "Unrecognized option: $1" + usage + ;; + esac + shift +done + +## Get information on the Wine environment + +export WINEPREFIX=${WINEPREFIX:-"$HOME/.wine"} + +# check wine prefix before invoking wine, so that we +# don't accidentally create one if the user screws up +if ! $do_makeprefix && [ -n "$WINEPREFIX" ] && ! [ -f "$WINEPREFIX/system.reg" ]; then + echo "$WINEPREFIX: Not a valid wine prefix." >&2 + exit 1 +fi + +export WINEDEBUG=-all +# disable mscoree and mshtml to avoid downloading +# wine gecko and mono +export WINEDLLOVERRIDES="mscoree,mshtml=" + +wine="wine" +wine64="wine64" +wineboot="wineboot" + +# $PATH is the way for user to control where wine is located (including custom Wine versions). +# Pure 64-bit Wine (non Wow64) requries skipping 32-bit steps. +# In such case, wine64 and winebooot will be present, but wine binary will be missing, +# however it can be present in other PATHs, so it shouldn't be used, to avoid versions mixing. +wine_path=$(dirname "$(command -v $wineboot)") +wow64=true +if ! [ -f "$wine_path/$wine" ]; then + wine=$wine64 + wow64=false +fi + +# resolve 32-bit and 64-bit system32 path +winever=$($wine --version | grep wine) +if [ -z "$winever" ]; then + echo "$wine: Not a wine executable. Check your $wine." >&2 + exit 1 +fi + +# ensure wine placeholder dlls are recreated +# if they are missing +$wineboot -u + +win64_sys_path=$($wine64 winepath -u 'C:\windows\system32' 2> /dev/null) +win64_sys_path="${win64_sys_path/$'\r'/}" +if $wow64; then + win32_sys_path=$($wine winepath -u 'C:\windows\system32' 2> /dev/null) + win32_sys_path="${win32_sys_path/$'\r'/}" +fi + +if [ -z "${win32_sys_path:-}" ] && [ -z "${win64_sys_path:-}" ]; then + echo 'Failed to resolve C:\windows\system32.' >&2 + exit 1 +fi + +## Utility functions + +install_file() { + $do_symlink && file_cmd="ln -sv" || file_cmd="install -m 755 -v" + + srcfile=$1 + dstfile=$2 + + if [ -f "${srcfile}.so" ]; then + srcfile="${srcfile}.so" + fi + + if ! [ -f "${srcfile}" ]; then + echo "${srcfile}: File not found. Skipping." >&2 + return 1 + fi + + if [ -n "$1" ]; then + if [ -f "${dstfile}" ] || [ -h "${dstfile}" ]; then + if ! [ -f "${dstfile}.old" ]; then + mv -v "${dstfile}" "${dstfile}.old" + else + rm -v "${dstfile}" + fi + fi + $file_cmd "${srcfile}" "${dstfile}" + else + echo "${dstfile}: File not found in wine prefix" >&2 + return 1 + fi +} + +uninstall_file() { + srcfile=$1 + dstfile=$2 + + if [ -f "${srcfile}.so" ]; then + srcfile="${srcfile}.so" + fi + + if ! [ -f "${srcfile}" ]; then + echo "${srcfile}: File not found. Skipping." >&2 + return 1 + fi + + if ! [ -f "${dstfile}" ] && ! [ -h "${dstfile}" ]; then + echo "${dstfile}: File not found. Skipping." >&2 + return 1 + fi + + if [ -f "${dstfile}.old" ]; then + rm -v "${dstfile}" + mv -v "${dstfile}.old" "${dstfile}" + return 0 + else + return 1 + fi +} + +install_override() { + dll=$(basename "$1") + if ! $wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v "$dll" /d native /f >/dev/null 2>&1; then + echo -e "Failed to add override for $dll" + exit 1 + fi +} + +uninstall_override() { + dll=$(basename "$1") + if ! $wine reg delete 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v "$dll" /f > /dev/null 2>&1; then + echo "Failed to remove override for $dll" + fi +} + +## Perform the requested command + +declare -A paths + +for target in "${!targets[@]}"; do + [ "${targets[$target]}" -eq 1 ] || continue + for dll in ${dlls[$target]}; do + dllname=$(basename "$dll") + basedir=$(dirname "$dll") + + if [ -n "${win32_sys_path:-}" ]; then + basedir32=${basedir}32_dir + paths["${!basedir32}/$dllname"]="$win32_sys_path/$dllname" + fi + if [ -n "${win64_sys_path:-}" ]; then + basedir64=${basedir}64_dir + paths["${!basedir64}/$dllname"]="$win64_sys_path/$dllname" + fi + done +done + +for srcpath in "${!paths[@]}"; do + "${action}_file" "$srcpath" "${paths["$srcpath"]}" + "${action}_override" "$(basename "$srcpath" .dll)" +done diff --git a/nixpkgs/pkgs/by-name/dx/dxvk_1/darwin-dxvk-compat.patch b/nixpkgs/pkgs/by-name/dx/dxvk_1/darwin-dxvk-compat.patch new file mode 100644 index 000000000000..99833a020cda --- /dev/null +++ b/nixpkgs/pkgs/by-name/dx/dxvk_1/darwin-dxvk-compat.patch @@ -0,0 +1,48 @@ +diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp +index 09f3559a..215787f9 100644 +--- a/src/d3d11/d3d11_device.cpp ++++ b/src/d3d11/d3d11_device.cpp +@@ -801,8 +801,12 @@ namespace dxvk { + InitReturnPtr(ppGeometryShader); + D3D11CommonShader module; + +- if (!m_dxvkDevice->features().extTransformFeedback.transformFeedback) +- return DXGI_ERROR_INVALID_CALL; ++ if (!m_dxvkDevice->features().extTransformFeedback.transformFeedback) { ++ Logger::err( ++ "D3D11: CreateGeometryShaderWithStreamOutput:" ++ "\n Transform feedback not supported by device"); ++ return S_OK; ++ } + + // Zero-init some counterss so that we can increment + // them while walking over the stream output entries +@@ -1920,7 +1924,7 @@ namespace dxvk { + DxvkDeviceFeatures supported = adapter->features(); + DxvkDeviceFeatures enabled = {}; + +- enabled.core.features.geometryShader = VK_TRUE; ++ enabled.core.features.geometryShader = supported.core.features.geometryShader; + enabled.core.features.robustBufferAccess = VK_TRUE; + enabled.core.features.shaderStorageImageWriteWithoutFormat = VK_TRUE; + enabled.core.features.depthBounds = supported.core.features.depthBounds; +@@ -1951,7 +1955,7 @@ namespace dxvk { + enabled.core.features.sampleRateShading = VK_TRUE; + enabled.core.features.samplerAnisotropy = supported.core.features.samplerAnisotropy; + enabled.core.features.shaderClipDistance = VK_TRUE; +- enabled.core.features.shaderCullDistance = VK_TRUE; ++ enabled.core.features.shaderCullDistance = supported.core.features.shaderCullDistance; + enabled.core.features.textureCompressionBC = VK_TRUE; + enabled.extDepthClipEnable.depthClipEnable = supported.extDepthClipEnable.depthClipEnable; + enabled.extHostQueryReset.hostQueryReset = VK_TRUE; +@@ -1971,8 +1975,8 @@ namespace dxvk { + enabled.core.features.logicOp = supported.core.features.logicOp; + enabled.core.features.shaderImageGatherExtended = VK_TRUE; + enabled.core.features.variableMultisampleRate = supported.core.features.variableMultisampleRate; +- enabled.extTransformFeedback.transformFeedback = VK_TRUE; +- enabled.extTransformFeedback.geometryStreams = VK_TRUE; ++ enabled.extTransformFeedback.transformFeedback = supported.extTransformFeedback.transformFeedback; ++ enabled.extTransformFeedback.geometryStreams = supported.extTransformFeedback.geometryStreams; + } + + if (featureLevel >= D3D_FEATURE_LEVEL_10_1) { diff --git a/nixpkgs/pkgs/by-name/dx/dxvk_1/darwin-thread-primitives.patch b/nixpkgs/pkgs/by-name/dx/dxvk_1/darwin-thread-primitives.patch new file mode 100644 index 000000000000..c008099407c5 --- /dev/null +++ b/nixpkgs/pkgs/by-name/dx/dxvk_1/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/nixpkgs/pkgs/by-name/dx/dxvk_1/package.nix b/nixpkgs/pkgs/by-name/dx/dxvk_1/package.nix new file mode 100644 index 000000000000..44a39eeaba25 --- /dev/null +++ b/nixpkgs/pkgs/by-name/dx/dxvk_1/package.nix @@ -0,0 +1,57 @@ +{ lib +, stdenv +, fetchFromGitHub +, glslang +, meson +, ninja +, windows +, pkgsBuildHost +, enableMoltenVKCompat ? false +}: + +let + isCross = stdenv.hostPlatform != stdenv.targetPlatform; +in +stdenv.mkDerivation (finalAttrs: { + pname = "dxvk"; + version = "1.10.3"; + + src = fetchFromGitHub { + owner = "doitsujin"; + repo = "dxvk"; + rev = "v${finalAttrs.version}"; + hash = "sha256-T93ZylxzJGprrP+j6axZwl2d3hJowMCUOKNjIyNzkmE="; + }; + + # These patches are required when using DXVK with Wine on Darwin. + patches = lib.optionals enableMoltenVKCompat [ + # 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 + ]; + + nativeBuildInputs = [ glslang meson ninja ]; + buildInputs = [ windows.pthreads ]; + + mesonFlags = + let + arch = if stdenv.is32bit then "32" else "64"; + in + [ + "--buildtype" "release" + "--prefix" "${placeholder "out"}" + ] + ++ lib.optionals isCross [ "--cross-file" "build-win${arch}.txt" ]; + + 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 = lib.platforms.windows; + }; +}) diff --git a/nixpkgs/pkgs/by-name/dx/dxvk_2/package.nix b/nixpkgs/pkgs/by-name/dx/dxvk_2/package.nix new file mode 100644 index 000000000000..e1fa64ffee05 --- /dev/null +++ b/nixpkgs/pkgs/by-name/dx/dxvk_2/package.nix @@ -0,0 +1,77 @@ +{ 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. +assert !sdl2Support || !glfwSupport; + +let + isCross = stdenv.hostPlatform != stdenv.targetPlatform; + isWindows = stdenv.hostPlatform.uname.system == "Windows"; +in +stdenv.mkDerivation (finalAttrs: { + pname = "dxvk"; + version = "2.3"; + + src = fetchFromGitHub { + owner = "doitsujin"; + repo = "dxvk"; + rev = "v${finalAttrs.version}"; + hash = "sha256-RU+B0XfphD5HHW/vSzqHLUaGS3E31d5sOLp3lMmrCB8="; + fetchSubmodules = true; # Needed for the DirectX headers and libdisplay-info + }; + + postPatch = '' + substituteInPlace "subprojects/libdisplay-info/tool/gen-search-table.py" \ + --replace "/usr/bin/env python3" "${lib.getBin pkgsBuildHost.python3}/bin/python3" + ''; + + nativeBuildInputs = [ glslang meson ninja ]; + buildInputs = [ spirv-headers vulkan-headers ] + ++ lib.optionals (!isWindows && sdl2Support) [ SDL2 ] + ++ lib.optionals (!isWindows && glfwSupport) [ glfw ] + ++ lib.optionals isWindows [ windows.pthreads ]; + + # Build with the Vulkan SDK in nixpkgs. + preConfigure = '' + rm -rf include/spirv/include include/vulkan/include + mkdir -p include/spirv/include include/vulkan/include + ''; + + mesonFlags = + let + arch = if stdenv.is32bit then "32" else "64"; + in + [ + "--buildtype" "release" + "--prefix" "${placeholder "out"}" + ] + ++ lib.optionals isCross [ "--cross-file" "build-win${arch}.txt" ] + ++ lib.optional glfwSupport "-Ddxvk_native_wsi=glfw"; + + doCheck = !isCross; + + passthru.updateScript = gitUpdater { rev-prefix = "v"; }; + + 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 = lib.platforms.windows ++ lib.platforms.linux; + }; +}) |