diff options
Diffstat (limited to 'dxvk-async.patch')
-rw-r--r-- | dxvk-async.patch | 446 |
1 files changed, 0 insertions, 446 deletions
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', |