diff options
-rw-r--r-- | .SRCINFO | 31 | ||||
-rw-r--r-- | PKGBUILD | 132 | ||||
-rw-r--r-- | dxvk-async.patch | 446 | ||||
-rw-r--r-- | dxvk-extraopts.patch | 34 | ||||
-rw-r--r-- | extraopts.patch | 70 | ||||
-rw-r--r-- | setup_dxvk | 2 | ||||
-rwxr-xr-x | setup_dxvk.sh | 236 |
7 files changed, 358 insertions, 593 deletions
@@ -1,7 +1,7 @@ pkgbase = dxvk-mingw pkgdesc = Vulkan-based implementation of D3D9, D3D10 and D3D11 for Linux / Wine, MingW version - pkgver = 1.6.1 - pkgrel = 2 + pkgver = 2.3.1 + pkgrel = 1 url = https://github.com/doitsujin/dxvk arch = x86_64 license = zlib/libpng @@ -10,23 +10,24 @@ pkgbase = dxvk-mingw makedepends = glslang makedepends = git makedepends = mingw-w64-gcc - depends = vulkan-icd-loader - depends = wine>=4.0rc1 - depends = lib32-vulkan-icd-loader - depends = bash provides = dxvk provides = d9vk - provides = dxvk=1.6.1 + provides = dxvk=2.3.1 conflicts = dxvk conflicts = d9vk - source = git+https://github.com/doitsujin/dxvk.git#tag=v1.6.1 + options = !lto + options = !staticlibs + source = git+https://github.com/doitsujin/dxvk.git#tag=v2.3.1 + source = dxvk-extraopts.patch + source = setup_dxvk.sh source = setup_dxvk - source = dxvk-async.patch - source = extraopts.patch - sha256sums = SKIP - sha256sums = b2413cabd8cca56e2d308ef5513edf1c7f909036ed2ccfeae17536a0e864dc96 - sha256sums = 6ff286091c20327e67252e1e6812830a42c990d1ee56541023eb217712209f3c - sha256sums = acde3a23166f79fa87ab090200be2aabaf16e5876ce19b8270ad1179bb0bc7a5 + sha256sums = 203b336366b16612b01bc5c220bdeeee633e6fdbf15f23559c826eac7b59beeb + sha256sums = bcc15521e4c7f966a0192a1dabb7fb4935b33db39344ab5b861f9d81486f1362 + sha256sums = c3daf448a0460f36ac471d2d4982874207888148ac3f03fbc2f003eccc2c2a45 + sha256sums = c1f6a18b03d1612b60f8081428f00cfac5e66315fe9d42719f01cf5564deeeff pkgname = dxvk-mingw - + depends = vulkan-icd-loader + depends = lib32-vulkan-icd-loader + depends = wine + depends = bash @@ -1,102 +1,112 @@ # Maintainer: loathingkernel <loathingkernel @at gmail .dot com> pkgname=dxvk-mingw -pkgver=1.6.1 -pkgrel=2 +pkgver=2.3.1 +pkgrel=1 pkgdesc='Vulkan-based implementation of D3D9, D3D10 and D3D11 for Linux / Wine, MingW version' arch=('x86_64') url="https://github.com/doitsujin/dxvk" license=('zlib/libpng') -depends=('vulkan-icd-loader' 'wine>=4.0rc1' 'lib32-vulkan-icd-loader' 'bash') makedepends=('ninja' 'meson>=0.43' 'glslang' 'git' 'mingw-w64-gcc') provides=('dxvk' 'd9vk' "dxvk=$pkgver") conflicts=('dxvk' 'd9vk') +options=(!lto !staticlibs) source=( "git+https://github.com/doitsujin/dxvk.git#tag=v$pkgver" + "dxvk-extraopts.patch" + "setup_dxvk.sh" "setup_dxvk" - "dxvk-async.patch" - "extraopts.patch" -) -sha256sums=( - "SKIP" - "b2413cabd8cca56e2d308ef5513edf1c7f909036ed2ccfeae17536a0e864dc96" - "6ff286091c20327e67252e1e6812830a42c990d1ee56541023eb217712209f3c" - "acde3a23166f79fa87ab090200be2aabaf16e5876ce19b8270ad1179bb0bc7a5" ) prepare() { cd dxvk + # Explicitly set origin URL for submodules using relative paths + git remote set-url origin https://github.com/doitsujin/dxvk.git + git submodule update --init --filter=tree:0 --recursive + # Uncomment to enable extra optimizations # Patch crossfiles with extra optimizations from makepkg.conf - patch -p1 -i "$srcdir"/extraopts.patch - local dxvk_cflags="$CFLAGS" - local dxvk_ldflags="$LDFLAGS" - # Filter known bad flags before applying optimizations - # If using -march=native and the CPU supports AVX, launching a d3d9 - # game can cause an Unhandled exception. The cause seems to be the - # combination of AVX instructions and tree vectorization (implied by O3), - # all tested archictures from sandybridge to haswell are affected. - # Disabling AVX (and AVX2 as a side-effect). - # Relevant Wine issues - # https://bugs.winehq.org/show_bug.cgi?id=45289 - # https://bugs.winehq.org/show_bug.cgi?id=43516 - dxvk_cflags+=" -mno-avx" - # Filter fstack-protector{ ,-all,-strong} flag for MingW. - # https://github.com/Joshua-Ashton/d9vk/issues/476 - #dxvk_cflags+=" -fno-stack-protector" - dxvk_cflags="${dxvk_cflags// -fstack-protector*([\-all|\-strong])/}" - # Adjust optimization level in meson arguments. This is ignored - # anyway because meson sets its own optimization level. - dxvk_cflags="${dxvk_cflags// -O+([0-3s]|fast)/}" - # Doesn't compile with these flags in MingW so remove them. - # They are also filtered in Wine PKGBUILDs so remove them - # for winelib versions too. - dxvk_cflags="${dxvk_cflags/ -fno-plt/}" - dxvk_ldflags="${dxvk_ldflags/,-z,now/}" - dxvk_ldflags="${dxvk_ldflags/,-z,relro/}" + patch -p1 -i "$srcdir"/dxvk-extraopts.patch + + # By default export FLAGS used by proton and ignore makepkg + # This overrides FLAGS from makepkg.conf, if you comment these you are on your own + # If you want the "best" possible optimizations for your system you can use + # `-march=native` and remove the `-mtune=core-avx2` option. + + local -a split=($CFLAGS) + local -A flags + for opt in "${split[@]}"; do flags["${opt%%=*}"]="${opt##*=}"; done + local march="${flags["-march"]:-nocona}" + local mtune="generic" #"${flags["-mtune"]:-core-avx2}" + + CFLAGS="-O3 -march=$march -mtune=$mtune -pipe" + CXXFLAGS="-O3 -march=$march -mtune=$mtune -pipe" + LDFLAGS="-Wl,-O1,--sort-common,--as-needed" + + # These flags are taken from Proton + CFLAGS+=" -mfpmath=sse -fwrapv -fno-strict-aliasing" + CXXFLAGS+=" -mfpmath=sse -fwrapv -fno-strict-aliasing -std=c++17" + LDFLAGS+=" -Wl,--file-alignment,4096" + + # AVX is "hard" disabled for 32bit in any case. + # AVX/AVX2 for 64bit is disabled below. + # Seems unnecessery for 64bit if -mtune=generic is used + #CFLAGS+=" -mno-avx2 -mno-avx" + #CXXFLAGS+=" -mno-avx2 -mno-avx" + + export CFLAGS CXXFLAGS LDFLAGS + + local cross_ldflags="$LDFLAGS" + + local cross_cflags="$CFLAGS -mcmodel=small" + local cross_cxxflags="$CXXFLAGS -mcmodel=small" sed -i build-win64.txt \ - -e "s|@CARGS@|\'${dxvk_cflags// /\',\'}\'|g" \ - -e "s|@LDARGS@|\'${dxvk_ldflags// /\',\'}\'|g" + -e "s|@CARGS@|\'${cross_cflags// /\',\'}\'|g" \ + -e "s|@CXXARGS@|\'${cross_cxxflags// /\',\'}\'|g" \ + -e "s|@LDARGS@|\'${cross_ldflags// /\',\'}\'|g" + + local cross_cflags="$CFLAGS -mstackrealign -mno-avx" + local cross_cxxflags="$CXXFLAGS -mstackrealign -mno-avx" sed -i build-win32.txt \ - -e "s|@CARGS@|\'${dxvk_cflags// /\',\'}\'|g" \ - -e "s|@LDARGS@|\'${dxvk_ldflags// /\',\'}\'|g" - - # Uncomment to enable dxvk async patch. - # Enable at your own risk. If you don't know what it is, - # and its implications, leave it as is. You have been warned. - # I am not liable if anything happens to you by using it. - # Patch enables async by default. YOU HAVE BEEN WARNED. - #patch -p1 -i "$srcdir"/dxvk-async.patch + -e "s|@CARGS@|\'${cross_cflags// /\',\'}\'|g" \ + -e "s|@CXXARGS@|\'${cross_cxxflags// /\',\'}\'|g" \ + -e "s|@LDARGS@|\'${cross_ldflags// /\',\'}\'|g" } build() { - meson dxvk "build/x64" \ + meson setup dxvk "build/x64" \ --cross-file dxvk/build-win64.txt \ --prefix "/usr/share/dxvk/x64" \ --bindir "" --libdir "" \ - --buildtype "release" \ - --optimization=3 \ - --strip \ - -Denable_tests=false + --buildtype "plain" \ + --force-fallback-for=libdisplay-info \ + --strip ninja -C "build/x64" -v - meson dxvk "build/x32" \ + meson setup dxvk "build/x32" \ --cross-file dxvk/build-win32.txt \ --prefix "/usr/share/dxvk/x32" \ --bindir "" --libdir "" \ - --buildtype "release" \ - --optimization=3 \ - --strip \ - -Denable_tests=false + --buildtype "plain" \ + --force-fallback-for=libdisplay-info \ + --strip ninja -C "build/x32" -v } package() { + depends=('vulkan-icd-loader' 'lib32-vulkan-icd-loader' 'wine' 'bash') + DESTDIR="$pkgdir" ninja -C "build/x32" install DESTDIR="$pkgdir" ninja -C "build/x64" install - install -Dm 755 -t "$pkgdir/usr/share/dxvk" dxvk/setup_dxvk.sh - install -Dm 644 -t "$pkgdir/usr/share/doc/dxvk" dxvk/dxvk.conf - install -Dm 644 -t "$pkgdir/usr/share/$pkgname" dxvk/LICENSE + install -Dm 755 -t "$pkgdir/usr/share/dxvk" setup_dxvk.sh + install -Dm 644 -t "$pkgdir/usr/share/dxvk" dxvk/dxvk.conf + install -Dm 644 -t "$pkgdir/usr/share/doc/$pkgname" dxvk/README.md + install -Dm 644 -t "$pkgdir/usr/share/licenses/$pkgname" dxvk/LICENSE install -Dm 755 -t "$pkgdir/usr/bin" setup_dxvk } + +sha256sums=('203b336366b16612b01bc5c220bdeeee633e6fdbf15f23559c826eac7b59beeb' + 'bcc15521e4c7f966a0192a1dabb7fb4935b33db39344ab5b861f9d81486f1362' + 'c3daf448a0460f36ac471d2d4982874207888148ac3f03fbc2f003eccc2c2a45' + 'c1f6a18b03d1612b60f8081428f00cfac5e66315fe9d42719f01cf5564deeeff') diff --git a/dxvk-async.patch b/dxvk-async.patch deleted file mode 100644 index 19c506c4964f..000000000000 --- a/dxvk-async.patch +++ /dev/null @@ -1,446 +0,0 @@ -From dfac76f528d0fc88ecbfe27ccb87483840828b9b Mon Sep 17 00:00:00 2001 -From: Tk-Glitch <ti3nou@gmail.com> -Date: Sat, 28 Sep 2019 18:59:04 +0200 -Subject: Async pipecompiler rebase against DXVK - d128d776ad906d6b8d3941eda7b7ee679346dbaf - - -diff --git a/meson.build b/meson.build -index 9a519e46..dea82ee1 100644 ---- a/meson.build -+++ b/meson.build -@@ -101,7 +101,7 @@ else - endif - - dxvk_version = vcs_tag( -- command: ['git', 'describe', '--dirty=+'], -+ command: ['git', 'describe', '--dirty=-async'], - input: 'version.h.in', - output: 'version.h') - -diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp -index b4f679fa..13c86d8f 100644 ---- a/src/dxvk/dxvk_context.cpp -+++ b/src/dxvk/dxvk_context.cpp -@@ -606,7 +606,7 @@ namespace dxvk { - const Rc<DxvkImageView>& imageView, - VkImageAspectFlags clearAspects, - VkClearValue clearValue) { -- this->updateFramebuffer(); -+ this->updateFramebuffer(false); - - // Prepare attachment ops - DxvkColorAttachmentOps colorOp; -@@ -2433,7 +2433,7 @@ namespace dxvk { - VkExtent3D extent, - VkImageAspectFlags aspect, - VkClearValue value) { -- this->updateFramebuffer(); -+ this->updateFramebuffer(false); - - // Find out if the render target view is currently bound, - // so that we can avoid spilling the render pass if it is. -@@ -3652,7 +3652,7 @@ namespace dxvk { - : DxvkContextFlag::GpDirtyStencilRef); - - // Retrieve and bind actual Vulkan pipeline handle -- m_gpActivePipeline = m_state.gp.pipeline->getPipelineHandle(m_state.gp.state, m_state.om.framebuffer->getRenderPass()); -+ m_gpActivePipeline = m_state.gp.pipeline->getPipelineHandle(m_state.gp.state, m_state.om.framebuffer->getRenderPass(), this->checkAsyncCompilationCompat()); - - if (unlikely(!m_gpActivePipeline)) - return false; -@@ -3969,7 +3969,7 @@ namespace dxvk { - } - - -- void DxvkContext::updateFramebuffer() { -+ void DxvkContext::updateFramebuffer(bool isDraw) { - if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) { - m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer); - -@@ -3988,6 +3988,11 @@ namespace dxvk { - : VkComponentMapping(); - } - -+ if (isDraw) { -+ for (uint32_t i = 0; i < fb->numAttachments(); i++) -+ fb->getAttachment(i).view->setRtBindingFrameId(m_device->getCurrentFrameId()); -+ } -+ - m_flags.set(DxvkContextFlag::GpDirtyPipelineState); - } - } -@@ -4205,7 +4210,7 @@ namespace dxvk { - template<bool Indexed> - void DxvkContext::commitGraphicsState() { - if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) -- this->updateFramebuffer(); -+ this->updateFramebuffer(true); - - if (!m_flags.test(DxvkContextFlag::GpRenderPassBound)) - this->startRenderPass(); -@@ -4465,4 +4470,13 @@ namespace dxvk { - } - } - --} -\ No newline at end of file -+ -+ bool DxvkContext::checkAsyncCompilationCompat() { -+ bool fbCompat = true; -+ for (uint32_t i = 0; fbCompat && i < m_state.om.framebuffer->numAttachments(); i++) { -+ const auto& attachment = m_state.om.framebuffer->getAttachment(i); -+ fbCompat &= attachment.view->getRtBindingAsyncCompilationCompat(); -+ } -+ return fbCompat; -+ } -+} -diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h -index f54f5321..0984d085 100644 ---- a/src/dxvk/dxvk_context.h -+++ b/src/dxvk/dxvk_context.h -@@ -1141,7 +1141,7 @@ namespace dxvk { - VkDescriptorSet set, - const DxvkPipelineLayout* layout); - -- void updateFramebuffer(); -+ void updateFramebuffer(bool isDraw); - - void updateIndexBufferBinding(); - void updateVertexBufferBindings(); -@@ -1180,6 +1180,7 @@ namespace dxvk { - - void trackDrawBuffer(); - -+ bool checkAsyncCompilationCompat(); - }; - --} -\ No newline at end of file -+} -diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp -index 5e05b425..8586c794 100644 ---- a/src/dxvk/dxvk_graphics.cpp -+++ b/src/dxvk/dxvk_graphics.cpp -@@ -75,8 +75,6 @@ namespace dxvk { - - - DxvkGraphicsPipeline::~DxvkGraphicsPipeline() { -- for (const auto& instance : m_pipelines) -- this->destroyPipeline(instance.pipeline()); - } - - -@@ -96,7 +94,8 @@ namespace dxvk { - - VkPipeline DxvkGraphicsPipeline::getPipelineHandle( - const DxvkGraphicsPipelineStateInfo& state, -- const DxvkRenderPass* renderPass) { -+ const DxvkRenderPass* renderPass, -+ bool async) { - DxvkGraphicsPipelineInstance* instance = nullptr; - - { std::lock_guard<sync::Spinlock> lock(m_mutex); -@@ -105,10 +104,13 @@ namespace dxvk { - - if (instance) - return instance->pipeline(); -- -- instance = this->createInstance(state, renderPass); -+ -+ if (async && m_pipeMgr->m_compiler != nullptr) -+ m_pipeMgr->m_compiler->queueCompilation(this, state, renderPass); -+ else -+ instance = this->createInstance(state, renderPass); - } -- -+ - if (!instance) - return VK_NULL_HANDLE; - -diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h -index 168e9714..07f0883d 100644 ---- a/src/dxvk/dxvk_graphics.h -+++ b/src/dxvk/dxvk_graphics.h -@@ -247,11 +247,13 @@ namespace dxvk { - * state. If necessary, a new pipeline will be created. - * \param [in] state Pipeline state vector - * \param [in] renderPass The render pass -+ * \param [in] async Compile asynchronously - * \returns Pipeline handle - */ - VkPipeline getPipelineHandle( - const DxvkGraphicsPipelineStateInfo& state, -- const DxvkRenderPass* renderPass); -+ const DxvkRenderPass* renderPass, -+ bool async); - - /** - * \brief Compiles a pipeline -diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h -index 8f82d65a..156f6054 100644 ---- a/src/dxvk/dxvk_image.h -+++ b/src/dxvk/dxvk_image.h -@@ -442,6 +442,37 @@ namespace dxvk { - return result; - } - -+ /** -+ * \brief Sets render target usage frame number -+ * -+ * The image view will track internally when -+ * it was last used as a render target. This -+ * info is used for async shader compilation. -+ * \param [in] frameId Frame number -+ */ -+ void setRtBindingFrameId(uint32_t frameId) { -+ if (frameId != m_rtBindingFrameId) { -+ if (frameId == m_rtBindingFrameId + 1) -+ m_rtBindingFrameCount += 1; -+ else -+ m_rtBindingFrameCount = 0; -+ -+ m_rtBindingFrameId = frameId; -+ } -+ } -+ -+ /** -+ * \brief Checks for async pipeline compatibility -+ * -+ * Asynchronous pipeline compilation may be enabled if the -+ * render target has been drawn to in the previous frames. -+ * \param [in] frameId Current frame ID -+ * \returns \c true if async compilation is supported -+ */ -+ bool getRtBindingAsyncCompilationCompat() const { -+ return m_rtBindingFrameCount >= 5; -+ } -+ - private: - - Rc<vk::DeviceFn> m_vkd; -@@ -450,6 +481,9 @@ namespace dxvk { - DxvkImageViewCreateInfo m_info; - VkImageView m_views[ViewCount]; - -+ uint32_t m_rtBindingFrameId = 0; -+ uint32_t m_rtBindingFrameCount = 0; -+ - void createView(VkImageViewType type, uint32_t numLayers); - - }; -diff --git a/src/dxvk/dxvk_options.cpp b/src/dxvk/dxvk_options.cpp -index 394feabb..df05ecd8 100644 ---- a/src/dxvk/dxvk_options.cpp -+++ b/src/dxvk/dxvk_options.cpp -@@ -5,6 +5,7 @@ namespace dxvk { - DxvkOptions::DxvkOptions(const Config& config) { - enableStateCache = config.getOption<bool> ("dxvk.enableStateCache", true); - enableOpenVR = config.getOption<bool> ("dxvk.enableOpenVR", true); -+ useAsync = config.getOption<bool> ("dxvk.useAsync", true); - numCompilerThreads = config.getOption<int32_t> ("dxvk.numCompilerThreads", 0); - asyncPresent = config.getOption<Tristate>("dxvk.asyncPresent", Tristate::Auto); - useRawSsbo = config.getOption<Tristate>("dxvk.useRawSsbo", Tristate::Auto); -diff --git a/src/dxvk/dxvk_options.h b/src/dxvk/dxvk_options.h -index 447294b5..571d6c15 100644 ---- a/src/dxvk/dxvk_options.h -+++ b/src/dxvk/dxvk_options.h -@@ -10,6 +10,7 @@ namespace dxvk { - - /// Enable state cache - bool enableStateCache; -+ bool useAsync; - - /// Use transfer queue if available - bool enableTransferQueue; -diff --git a/src/dxvk/dxvk_pipecompiler.cpp b/src/dxvk/dxvk_pipecompiler.cpp -new file mode 100644 -index 00000000..cfef228a ---- /dev/null -+++ b/src/dxvk/dxvk_pipecompiler.cpp -@@ -0,0 +1,69 @@ -+#include "dxvk_graphics.h" -+#include "dxvk_pipecompiler.h" -+ -+namespace dxvk { -+ -+ DxvkPipelineCompiler::DxvkPipelineCompiler() { -+ uint32_t sysCpuCount = dxvk::thread::hardware_concurrency(); -+ uint32_t threadCount = sysCpuCount > 2 ? sysCpuCount - 2 : 1; -+ -+ Logger::info(str::format( -+ "DxvkPipelineCompiler: Using ", -+ threadCount, " workers")); -+ -+ // Start the compiler threads -+ m_compilerThreads.resize(threadCount); -+ -+ for (uint32_t i = 0; i < threadCount; i++) { -+ m_compilerThreads.at(i) = dxvk::thread( -+ [this] { this->runCompilerThread(); }); -+ } -+ } -+ -+ -+ DxvkPipelineCompiler::~DxvkPipelineCompiler() { -+ { std::unique_lock<std::mutex> lock(m_compilerLock); -+ m_compilerStop.store(true); -+ } -+ -+ m_compilerCond.notify_all(); -+ for (auto& thread : m_compilerThreads) -+ thread.join(); -+ } -+ -+ -+ void DxvkPipelineCompiler::queueCompilation( -+ DxvkGraphicsPipeline* pipeline, -+ const DxvkGraphicsPipelineStateInfo& state, -+ const DxvkRenderPass* renderPass) { -+ std::unique_lock<std::mutex> lock(m_compilerLock); -+ m_compilerQueue.push({ pipeline, state, renderPass }); -+ m_compilerCond.notify_one(); -+ } -+ -+ -+ void DxvkPipelineCompiler::runCompilerThread() { -+ env::setThreadName("dxvk-pcompiler"); -+ -+ while (!m_compilerStop.load()) { -+ PipelineEntry entry; -+ -+ { std::unique_lock<std::mutex> lock(m_compilerLock); -+ -+ m_compilerCond.wait(lock, [this] { -+ return m_compilerStop.load() -+ || m_compilerQueue.size() != 0; -+ }); -+ -+ if (m_compilerQueue.size() != 0) { -+ entry = std::move(m_compilerQueue.front()); -+ m_compilerQueue.pop(); -+ } -+ } -+ -+ if (entry.pipeline != nullptr && entry.renderPass != nullptr) -+ entry.pipeline->compilePipeline(entry.state, entry.renderPass); -+ } -+ } -+ -+} -diff --git a/src/dxvk/dxvk_pipecompiler.h b/src/dxvk/dxvk_pipecompiler.h -new file mode 100644 -index 00000000..a82fff60 ---- /dev/null -+++ b/src/dxvk/dxvk_pipecompiler.h -@@ -0,0 +1,60 @@ -+#pragma once -+ -+#include <atomic> -+#include <condition_variable> -+#include <mutex> -+#include <queue> -+ -+#include "../util/thread.h" -+#include "dxvk_include.h" -+ -+namespace dxvk { -+ -+ class DxvkGraphicsPipeline; -+ class DxvkGraphicsPipelineStateInfo; -+ -+ /** -+ * \brief Pipeline compiler -+ * -+ * Asynchronous pipeline compiler -+ */ -+ class DxvkPipelineCompiler : public RcObject { -+ -+ public: -+ -+ DxvkPipelineCompiler(); -+ ~DxvkPipelineCompiler(); -+ -+ /** -+ * \brief Compiles a pipeline asynchronously -+ * -+ * This should be used to compile graphics -+ * pipeline instances asynchronously. -+ * \param [in] pipeline The pipeline object -+ * \param [in] state The pipeline state info object -+ * \param [in] renderPass -+ */ -+ void queueCompilation( -+ DxvkGraphicsPipeline* pipeline, -+ const DxvkGraphicsPipelineStateInfo& state, -+ const DxvkRenderPass* renderPass); -+ -+ private: -+ -+ struct PipelineEntry { -+ DxvkGraphicsPipeline* pipeline = nullptr; -+ DxvkGraphicsPipelineStateInfo state; -+ const DxvkRenderPass* renderPass = nullptr; -+ }; -+ -+ std::atomic<bool> m_compilerStop = { false }; -+ std::mutex m_compilerLock; -+ std::condition_variable m_compilerCond; -+ std::queue<PipelineEntry> m_compilerQueue; -+ std::vector<dxvk::thread> m_compilerThreads; -+ -+ void runCompilerThread(); -+ -+ }; -+ -+} -diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp -index 378bb3d1..3323f926 100644 ---- a/src/dxvk/dxvk_pipemanager.cpp -+++ b/src/dxvk/dxvk_pipemanager.cpp -@@ -45,9 +45,13 @@ namespace dxvk { - : m_device (device), - m_cache (new DxvkPipelineCache(device->vkd())) { - std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE"); -+ std::string useAsync = env::getEnvVar("DXVK_ASYNC"); - - if (useStateCache != "0" && device->config().enableStateCache) - m_stateCache = new DxvkStateCache(device, this, passManager); -+ -+ if (useAsync != "0" || device->config().useAsync) -+ m_compiler = new DxvkPipelineCompiler(); - } - - -diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h -index f0087d15..29e758c7 100644 ---- a/src/dxvk/dxvk_pipemanager.h -+++ b/src/dxvk/dxvk_pipemanager.h -@@ -6,6 +6,7 @@ - - #include "dxvk_compute.h" - #include "dxvk_graphics.h" -+#include "dxvk_pipecompiler.h" - - namespace dxvk { - -@@ -107,6 +108,7 @@ namespace dxvk { - const DxvkDevice* m_device; - Rc<DxvkPipelineCache> m_cache; - Rc<DxvkStateCache> m_stateCache; -+ Rc<DxvkPipelineCompiler> m_compiler; - - std::atomic<uint32_t> m_numComputePipelines = { 0 }; - std::atomic<uint32_t> m_numGraphicsPipelines = { 0 }; -diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build -index 867f3002..f4c4336c 100644 ---- a/src/dxvk/meson.build -+++ b/src/dxvk/meson.build -@@ -82,6 +82,7 @@ dxvk_src = files([ - 'dxvk_openvr.cpp', - 'dxvk_options.cpp', - 'dxvk_pipecache.cpp', -+ 'dxvk_pipecompiler.cpp', - 'dxvk_pipelayout.cpp', - 'dxvk_pipemanager.cpp', - 'dxvk_queue.cpp', diff --git a/dxvk-extraopts.patch b/dxvk-extraopts.patch new file mode 100644 index 000000000000..49a77f486f42 --- /dev/null +++ b/dxvk-extraopts.patch @@ -0,0 +1,34 @@ +diff --git a/build-win32.txt b/build-win32.txt +index a1406832..748f5c1e 100644 +--- a/build-win32.txt ++++ b/build-win32.txt +@@ -4,6 +4,12 @@ cpp = 'i686-w64-mingw32-g++' + ar = 'i686-w64-mingw32-ar' + strip = 'i686-w64-mingw32-strip' + ++[built-in options] ++c_args=[@CARGS@] ++cpp_args=[@CXXARGS@] ++c_link_args = [@LDARGS@] ++cpp_link_args = [@LDARGS@] ++ + [properties] + needs_exe_wrapper = true + +diff --git a/build-win64.txt b/build-win64.txt +index 1aee4626..7d2e84f4 100644 +--- a/build-win64.txt ++++ b/build-win64.txt +@@ -4,6 +4,12 @@ cpp = 'x86_64-w64-mingw32-g++' + ar = 'x86_64-w64-mingw32-ar' + strip = 'x86_64-w64-mingw32-strip' + ++[built-in options] ++c_args=[@CARGS@] ++cpp_args=[@CXXARGS@] ++c_link_args = [@LDARGS@] ++cpp_link_args = [@LDARGS@] ++ + [properties] + needs_exe_wrapper = true + diff --git a/extraopts.patch b/extraopts.patch deleted file mode 100644 index 43a8fd6d10ec..000000000000 --- a/extraopts.patch +++ /dev/null @@ -1,70 +0,0 @@ -diff --git a/build-win32.txt b/build-win32.txt -index 0865fc5e..b93a280f 100644 ---- a/build-win32.txt -+++ b/build-win32.txt -@@ -5,10 +5,10 @@ ar = 'i686-w64-mingw32-ar' - strip = 'i686-w64-mingw32-strip' - - [properties] --c_args=['-msse', '-msse2'] --cpp_args=['-msse', '-msse2'] --c_link_args = ['-static', '-static-libgcc'] --cpp_link_args = ['-static', '-static-libgcc', '-static-libstdc++'] -+c_args=['-msse', '-msse2', @CARGS@] -+cpp_args=['-msse', '-msse2', @CARGS@] -+c_link_args = ['-static', '-static-libgcc', @LDARGS@] -+cpp_link_args = ['-static', '-static-libgcc', '-static-libstdc++', @LDARGS@] - needs_exe_wrapper = true - - [host_machine] -diff --git a/build-win64.txt b/build-win64.txt -index 2a7fbee3..9e3bfc2e 100644 ---- a/build-win64.txt -+++ b/build-win64.txt -@@ -5,8 +5,10 @@ ar = 'x86_64-w64-mingw32-ar' - strip = 'x86_64-w64-mingw32-strip' - - [properties] --c_link_args = ['-static', '-static-libgcc'] --cpp_link_args = ['-static', '-static-libgcc', '-static-libstdc++'] -+c_args=[@CARGS@] -+cpp_args=[@CARGS@] -+c_link_args = ['-static', '-static-libgcc', @LDARGS@] -+cpp_link_args = ['-static', '-static-libgcc', '-static-libstdc++', @LDARGS@] - needs_exe_wrapper = true - - [host_machine] -diff --git a/build-wine32.txt b/build-wine32.txt -index ba8d34a8..ecec2eb4 100644 ---- a/build-wine32.txt -+++ b/build-wine32.txt -@@ -7,9 +7,9 @@ strip = 'strip' - [properties] - needs_exe_wrapper = true - --c_args=['-m32', '-msse', '-msse2', '-fvisibility=hidden'] --cpp_args=['-m32', '-msse', '-msse2', '-fvisibility=hidden', '-fvisibility-inlines-hidden', '-D__WIDL_objidl_generated_name_0000000C='] --cpp_link_args=['-m32', '-mwindows'] -+c_args=['-m32', '-msse', '-msse2', '-fvisibility=hidden', @CARGS@] -+cpp_args=['-m32', '-msse', '-msse2', '-fvisibility=hidden', '-fvisibility-inlines-hidden', '-D__WIDL_objidl_generated_name_0000000C=', @CARGS@] -+cpp_link_args=['-m32', '-mwindows', @LDARGS@] - - [host_machine] - system = 'linux' -diff --git a/build-wine64.txt b/build-wine64.txt -index b3e028bb..fb9d98fd 100644 ---- a/build-wine64.txt -+++ b/build-wine64.txt -@@ -7,9 +7,9 @@ strip = 'strip' - [properties] - needs_exe_wrapper = true - --c_args=['-m64', '-fvisibility=hidden'] --cpp_args=['-m64', '-fvisibility=hidden', '-fvisibility-inlines-hidden', '-D__WIDL_objidl_generated_name_0000000C='] --cpp_link_args=['-m64', '-mwindows'] -+c_args=['-m64', '-fvisibility=hidden', @CARGS@] -+cpp_args=['-m64', '-fvisibility=hidden', '-fvisibility-inlines-hidden', '-D__WIDL_objidl_generated_name_0000000C=', @CARGS@] -+cpp_link_args=['-m64', '-mwindows', @LDARGS@] - - [host_machine] - system = 'linux' diff --git a/setup_dxvk b/setup_dxvk index 01a7b908b232..e162b8da6e84 100644 --- a/setup_dxvk +++ b/setup_dxvk @@ -1,2 +1,2 @@ #!/bin/sh -/usr/share/dxvk/setup_dxvk.sh $1 --symlink +/usr/share/dxvk/setup_dxvk.sh $@ diff --git a/setup_dxvk.sh b/setup_dxvk.sh new file mode 100755 index 000000000000..773a141b697c --- /dev/null +++ b/setup_dxvk.sh @@ -0,0 +1,236 @@ +#!/usr/bin/env bash + +# default directories +dxvk_lib32=${dxvk_lib32:-"x32"} +dxvk_lib64=${dxvk_lib64:-"x64"} + +# figure out where we are +basedir="$(dirname "$(readlink -f "$0")")" + +# figure out which action to perform +action="$1" + +case "$action" in +install) + ;; +uninstall) + ;; +*) + echo "Unrecognized action: $action" + echo "Usage: $0 [install|uninstall] [--without-dxgi] [--symlink]" + exit 1 +esac + +# process arguments +shift + +with_dxgi=true +file_cmd="cp -v --reflink=auto" + +while (($# > 0)); do + case "$1" in + "--without-dxgi") + with_dxgi=false + ;; + "--symlink") + file_cmd="ln -s -v" + ;; + esac + shift +done + +# check wine prefix before invoking wine, so that we +# don't accidentally create one if the user screws up +if [ -n "$WINEPREFIX" ] && ! [ -f "$WINEPREFIX/system.reg" ]; then + echo "$WINEPREFIX:"' Not a valid wine prefix.' >&2 + exit 1 +fi + +# find wine executable +export WINEDEBUG=-all +# disable mscoree and mshtml to avoid downloading +# wine gecko and mono +export WINEDLLOVERRIDES="mscoree,mshtml=" + +wineserver="wineserver" + +# $PATH is the way for user to control where wine is located (including custom Wine versions). +# Pure 64-bit Wine (non Wow64) requires 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 "$(which $wineserver)") +wine="$wine_path/wine" +wine64="$wine_path/wine64" +wineboot="$wine_path/wineboot" + +# Thank you winetricks! +get_file_arch() +{ + _W_file="$1" + # Assume ELF binaries for everything else + _W_ob_output="$(od -An -t x1 -j 0x12 -N 1 "${_W_file}" | tr -d "[:space:]")" + case "${_W_ob_output}" in + "3e") _W_file_arch="x86_64" ;; + "03"|"06") _W_file_arch="i386" ;; + *) _W_file_arch="" ;; + esac + + echo "${_W_file_arch}" +} + +if [ -z "$WINEARCH" ]; then + wine_arch=$(get_file_arch "$wine") + wine64_arch=$(get_file_arch "$wine64") + if [ "$wine_arch" == "x86_64" ] || [ "$wine64_arch" == "x86_64" ]; then + arch=win64 + elif [ "$wine_arch" == "i386" ] && [ "$wine64_arch" == "" ]; then + arch=win32 + fi +else + arch="$WINEARCH" +fi + +if ! [ -f "$wine64" ]; then + wine64="$wine" +fi + +if [ "$arch" == "win32" ]; then + wine64="$wine" +fi + +# resolve 32-bit and 64-bit system32 path +wine_ver="$($wineserver --version 2>&1 >/dev/null | grep Wine)" +if [ -z "$wine_ver" ]; then + echo "$wineserver:"' Not a wine executable. Check your wine install.' >&2 + exit 1 +fi + +# ensure wine placeholder dlls are recreated +# if they are missing +$wineboot -u + +system32_path=$($wine64 winepath.exe -u 'C:\windows\system32' 2> /dev/null) +system32_path="${system32_path/$'\r'/}" +syswow64_path=$($wine64 winepath.exe -u 'C:\windows\syswow64' 2> /dev/null) +syswow64_path="${syswow64_path/$'\r'/}" + +if [ -z "$syswow64_path" ] && [ -z "$system32_path" ]; then + echo 'Failed to resolve C:\windows\system32.' >&2 + exit 1 +fi + +# create native dll override +overrideDll() { + if ! $wine64 reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v "$1" /d native /f >/dev/null 2>&1; then + echo -e "Failed to add override for $1" + exit 1 + fi +} + +# remove dll override +restoreDll() { + if ! $wine64 reg delete 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v "$1" /f >/dev/null 2>&1; then + echo "Failed to remove override for $1" + fi +} + +# copy or link dxvk dll, back up original file +installFile() { + dstfile="${1}/${3}.dll" + srcfile="${basedir}/${2}/${3}.dll" + + 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 + else + touch "${dstfile}.old_none" + fi + $file_cmd "${srcfile}" "${dstfile}" + fi + return 0 +} + +# remove dxvk dll, restore original file +uninstallFile() { + dstfile="${1}/${3}.dll" + srcfile="${basedir}/${2}/${3}.dll" + + 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 + elif [ -f "${dstfile}.old_none" ]; then + rm -v "${dstfile}.old_none" + rm -v "${dstfile}" + return 0 + else + return 1 + fi +} + +install() { + if [ "$arch" == "win32" ]; then + lib="$dxvk_lib32" + dll="${1}" + else + lib="$dxvk_lib64" + dll="${1}" + fi + if installFile "$system32_path" "$lib" "$dll"; then + overrideDll "$dll" + fi + + if [ -d "$syswow64_path" ]; then + if installFile "$syswow64_path" "$dxvk_lib32" "$1"; then + overrideDll "$1" + fi + fi +} + +uninstall() { + if [ "$arch" == "win32" ]; then + lib="$dxvk_lib32" + dll="${1}" + else + lib="$dxvk_lib64" + dll="${1}" + fi + if uninstallFile "$system32_path" "$lib" "$dll"; then + restoreDll "$dll" + fi + + if [ -d "$syswow64_path" ]; then + if uninstallFile "$syswow64_path" "$dxvk_lib32" "$1"; then + restoreDll "$1" + fi + fi +} + +# skip dxgi during install if not explicitly +# enabled, but always try to uninstall it +if $with_dxgi || [ "$action" == "uninstall" ]; then + $action dxgi +fi + +$action d3d9 +$action d3d10core +$action d3d11 |