From cfb47918725bf3b4d0d478cf8e199dab1bf6ca5b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 10 May 2018 14:54:44 +0200 Subject: [PATCH] [dxvk] Use VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT Optimized versions of the pipelines will be compiled asynchronously. --- src/dxvk/dxvk_graphics.cpp | 40 ++++++++++++++++++++-------------- src/dxvk/dxvk_graphics.h | 24 +++++++++++--------- src/dxvk/dxvk_pipecompiler.cpp | 1 + src/dxvk/dxvk_pipecompiler.h | 5 ++++- src/dxvk/dxvk_pipemanager.cpp | 8 ++++--- src/dxvk/dxvk_pipemanager.h | 6 +++-- 6 files changed, 52 insertions(+), 32 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 5aa1519e0..52dd9014a 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -55,15 +55,16 @@ namespace dxvk { DxvkGraphicsPipeline::DxvkGraphicsPipeline( - const DxvkDevice* device, - const Rc& cache, - const Rc& vs, - const Rc& tcs, - const Rc& tes, - const Rc& gs, - const Rc& fs) + const DxvkDevice* device, + const Rc& cache, + const Rc& compiler, + const Rc& vs, + const Rc& tcs, + const Rc& tes, + const Rc& gs, + const Rc& fs) : m_device(device), m_vkd(device->vkd()), - m_cache(cache) { + m_cache(cache), m_compiler(compiler) { DxvkDescriptorSlotMapping slotMapping; if (vs != nullptr) vs ->defineResourceSlots(slotMapping); if (tcs != nullptr) tcs->defineResourceSlots(slotMapping); @@ -117,8 +118,8 @@ namespace dxvk { // If no pipeline instance exists with the given state // vector, create a new one and add it to the list. - VkPipeline newPipelineHandle = this->compilePipeline( - state, renderPassHandle, VK_NULL_HANDLE); + VkPipeline newPipelineHandle = this->compilePipeline(state, renderPassHandle, + VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT, VK_NULL_HANDLE); Rc newPipeline = new DxvkGraphicsPipelineInstance(m_device->vkd(), state, @@ -138,16 +139,20 @@ namespace dxvk { m_pipelines.push_back(newPipeline); stats.addCtr(DxvkStatCounter::PipeCountGraphics, 1); - return newPipeline->getPipeline(); } + + // Compile optimized pipeline asynchronously + m_compiler->queueCompilation(this, newPipeline); + return newPipelineHandle; } - void DxvkGraphicsPipeline::compilePipelineInstance( + void DxvkGraphicsPipeline::compileInstance( const Rc& instance) { // Compile an optimized version of the pipeline VkPipeline newPipelineHandle = this->compilePipeline( - instance->m_stateVector, instance->m_renderPass, VK_NULL_HANDLE); + instance->m_stateVector, instance->m_renderPass, + 0, VK_NULL_HANDLE); // If an optimized version has been compiled // in the meantime, discard the new pipeline @@ -171,6 +176,7 @@ namespace dxvk { VkPipeline DxvkGraphicsPipeline::compilePipeline( const DxvkGraphicsPipelineStateInfo& state, VkRenderPass renderPass, + VkPipelineCreateFlags createFlags, VkPipeline baseHandle) const { if (Logger::logLevel() <= LogLevel::Debug) { Logger::debug("Compiling graphics pipeline..."); @@ -324,9 +330,7 @@ namespace dxvk { VkGraphicsPipelineCreateInfo info; info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; info.pNext = nullptr; - info.flags = baseHandle == VK_NULL_HANDLE - ? VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT - : VK_PIPELINE_CREATE_DERIVATIVE_BIT; + info.flags = createFlags; info.stageCount = stages.size(); info.pStages = stages.data(); info.pVertexInputState = &viInfo; @@ -344,6 +348,10 @@ namespace dxvk { info.basePipelineHandle = baseHandle; info.basePipelineIndex = -1; + info.flags |= baseHandle == VK_NULL_HANDLE + ? VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT + : VK_PIPELINE_CREATE_DERIVATIVE_BIT; + if (tsInfo.patchControlPoints == 0) info.pTessellationState = nullptr; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index ec4a776ee..2032c3328 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -5,6 +5,7 @@ #include "dxvk_binding.h" #include "dxvk_constant_state.h" #include "dxvk_pipecache.h" +#include "dxvk_pipecompiler.h" #include "dxvk_pipelayout.h" #include "dxvk_renderpass.h" #include "dxvk_resource.h" @@ -175,13 +176,14 @@ namespace dxvk { public: DxvkGraphicsPipeline( - const DxvkDevice* device, - const Rc& cache, - const Rc& vs, - const Rc& tcs, - const Rc& tes, - const Rc& gs, - const Rc& fs); + const DxvkDevice* device, + const Rc& cache, + const Rc& compiler, + const Rc& vs, + const Rc& tcs, + const Rc& tes, + const Rc& gs, + const Rc& fs); ~DxvkGraphicsPipeline(); /** @@ -218,7 +220,7 @@ namespace dxvk { * and makes it available to the system. * \param [in] instance The pipeline instance */ - void compilePipelineInstance( + void compileInstance( const Rc& instance); private: @@ -232,8 +234,9 @@ namespace dxvk { const DxvkDevice* const m_device; const Rc m_vkd; - Rc m_cache; - Rc m_layout; + Rc m_cache; + Rc m_compiler; + Rc m_layout; Rc m_vs; Rc m_tcs; @@ -256,6 +259,7 @@ namespace dxvk { VkPipeline compilePipeline( const DxvkGraphicsPipelineStateInfo& state, VkRenderPass renderPass, + VkPipelineCreateFlags createFlags, VkPipeline baseHandle) const; bool validatePipelineState( diff --git a/src/dxvk/dxvk_pipecompiler.cpp b/src/dxvk/dxvk_pipecompiler.cpp index 0134527a7..51d653ef7 100644 --- a/src/dxvk/dxvk_pipecompiler.cpp +++ b/src/dxvk/dxvk_pipecompiler.cpp @@ -1,3 +1,4 @@ +#include "dxvk_graphics.h" #include "dxvk_pipecompiler.h" namespace dxvk { diff --git a/src/dxvk/dxvk_pipecompiler.h b/src/dxvk/dxvk_pipecompiler.h index 428ad2097..ca6cd9444 100644 --- a/src/dxvk/dxvk_pipecompiler.h +++ b/src/dxvk/dxvk_pipecompiler.h @@ -6,10 +6,13 @@ #include #include -#include "dxvk_graphics.h" +#include "dxvk_include.h" namespace dxvk { + class DxvkGraphicsPipeline; + class DxvkGraphicsPipelineInstance; + /** * \brief Pipeline compiler * diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index c3b617fd5..ae5da3075 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -39,7 +39,9 @@ namespace dxvk { DxvkPipelineManager::DxvkPipelineManager(const DxvkDevice* device) - : m_device(device), m_cache(new DxvkPipelineCache(device->vkd())) { + : m_device (device), + m_cache (new DxvkPipelineCache(device->vkd())), + m_compiler(new DxvkPipelineCompiler()) { } @@ -93,8 +95,8 @@ namespace dxvk { if (pair != m_graphicsPipelines.end()) return pair->second; - const Rc pipeline - = new DxvkGraphicsPipeline(m_device, m_cache, vs, tcs, tes, gs, fs); + Rc pipeline = new DxvkGraphicsPipeline( + m_device, m_cache, m_compiler, vs, tcs, tes, gs, fs); m_graphicsPipelines.insert(std::make_pair(key, pipeline)); return pipeline; diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 5dc62152d..8da847013 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -5,6 +5,7 @@ #include "dxvk_compute.h" #include "dxvk_graphics.h" +#include "dxvk_pipecompiler.h" namespace dxvk { @@ -96,8 +97,9 @@ namespace dxvk { private: - const DxvkDevice* m_device; - const Rc m_cache; + const DxvkDevice* m_device; + const Rc m_cache; + const Rc m_compiler; std::mutex m_mutex;