From 4a72cae1e61848b8bb0d8a7ea7d3cc31effbd404 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 21 Sep 2018 23:23:43 +0200 Subject: [PATCH] [dxvk] Enable state cache --- src/dxvk/dxvk_device.cpp | 7 ++++++- src/dxvk/dxvk_device.h | 7 +++++++ src/dxvk/dxvk_graphics.cpp | 21 +++++++++++++++++++++ src/dxvk/dxvk_graphics.h | 4 ++++ src/dxvk/dxvk_pipemanager.cpp | 19 ++++++++++++++++--- src/dxvk/dxvk_pipemanager.h | 20 ++++++++++++++++++-- 6 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 3cc2e10f..f64a3e2a 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -16,7 +16,7 @@ namespace dxvk { m_properties (adapter->deviceProperties()), m_memory (new DxvkMemoryAllocator (this)), m_renderPassPool (new DxvkRenderPassPool (vkd)), - m_pipelineManager (new DxvkPipelineManager (this)), + m_pipelineManager (new DxvkPipelineManager (this, m_renderPassPool.ptr())), m_metaClearObjects (new DxvkMetaClearObjects (vkd)), m_metaMipGenObjects (new DxvkMetaMipGenObjects (vkd)), m_metaResolveObjects(new DxvkMetaResolveObjects (vkd)), @@ -220,6 +220,11 @@ namespace dxvk { void DxvkDevice::initResources() { m_unboundResources.clearResources(this); } + + + void DxvkDevice::registerShader(const Rc& shader) { + m_pipelineManager->registerShader(shader); + } VkResult DxvkDevice::presentSwapImage( diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 95d5210f..39d239ba 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -309,6 +309,13 @@ namespace dxvk { */ void initResources(); + /** + * \brief Registers a shader + * \param [in] shader Newly compiled shader + */ + void registerShader( + const Rc& shader); + /** * \brief Presents a swap chain image * diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 8aebd0d9..aef0738d 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -5,6 +5,7 @@ #include "dxvk_graphics.h" #include "dxvk_pipemanager.h" #include "dxvk_spec_const.h" +#include "dxvk_state_cache.h" namespace dxvk { @@ -132,6 +133,9 @@ namespace dxvk { if (newPipelineBase == VK_NULL_HANDLE && newPipelineHandle != VK_NULL_HANDLE) m_basePipeline.compare_exchange_strong(newPipelineBase, newPipelineHandle); + if (newPipelineHandle != VK_NULL_HANDLE) + this->writePipelineStateToCache(state, renderPass.format()); + return newPipelineHandle; } @@ -398,6 +402,23 @@ namespace dxvk { } + void DxvkGraphicsPipeline::writePipelineStateToCache( + const DxvkGraphicsPipelineStateInfo& state, + const DxvkRenderPassFormat& format) const { + if (m_pipeMgr->m_stateCache == nullptr) + return; + + DxvkStateCacheKey key; + if (m_vs != nullptr) key.vs = m_vs->getShaderKey(); + if (m_tcs != nullptr) key.tcs = m_tcs->getShaderKey(); + if (m_tes != nullptr) key.tes = m_tes->getShaderKey(); + if (m_gs != nullptr) key.gs = m_gs->getShaderKey(); + if (m_fs != nullptr) key.fs = m_fs->getShaderKey(); + + m_pipeMgr->m_stateCache->addGraphicsPipeline(key, state, format); + } + + void DxvkGraphicsPipeline::logPipelineState( LogLevel level, const DxvkGraphicsPipelineStateInfo& state) const { diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 78e312f9..756ed924 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -226,6 +226,10 @@ namespace dxvk { bool validatePipelineState( const DxvkGraphicsPipelineStateInfo& state) const; + void writePipelineStateToCache( + const DxvkGraphicsPipelineStateInfo& state, + const DxvkRenderPassFormat& format) const; + void logPipelineState( LogLevel level, const DxvkGraphicsPipelineStateInfo& state) const; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index a1cb8515..1e27b8e5 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -1,5 +1,6 @@ #include "dxvk_device.h" #include "dxvk_pipemanager.h" +#include "dxvk_state_cache.h" namespace dxvk { @@ -38,10 +39,15 @@ namespace dxvk { } - DxvkPipelineManager::DxvkPipelineManager(const DxvkDevice* device) - : m_device (device), - m_cache (new DxvkPipelineCache(device->vkd())) { + DxvkPipelineManager::DxvkPipelineManager( + const DxvkDevice* device, + DxvkRenderPassPool* passManager) + : m_device (device), + m_cache (new DxvkPipelineCache(device->vkd())) { + std::string useStateCache = env::getEnvVar(L"DXVK_STATE_CACHE"); + if (useStateCache != "0") + m_stateCache = new DxvkStateCache(this, passManager); } @@ -101,6 +107,13 @@ namespace dxvk { return pipeline; } + + void DxvkPipelineManager::registerShader( + const Rc& shader) { + if (m_stateCache != nullptr) + m_stateCache->registerShader(shader); + } + DxvkPipelineCount DxvkPipelineManager::getPipelineCount() const { DxvkPipelineCount result; diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 8fd5dd35..e6356fa7 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -8,6 +8,8 @@ namespace dxvk { + class DxvkStateCache; + /** * \brief Pipeline count * @@ -71,7 +73,10 @@ namespace dxvk { friend class DxvkGraphicsPipeline; public: - DxvkPipelineManager(const DxvkDevice* device); + DxvkPipelineManager( + const DxvkDevice* device, + DxvkRenderPassPool* passManager); + ~DxvkPipelineManager(); /** @@ -106,16 +111,27 @@ namespace dxvk { const Rc& gs, const Rc& fs); + /* + * \brief Registers a shader + * + * Starts compiling pipelines asynchronously + * in case the state cache contains state + * vectors for this shader. + * \param [in] shader Newly compiled shader + */ + void registerShader( + const Rc& shader); + /** * \brief Retrieves total pipeline count * \returns Number of compute/graphics pipelines */ DxvkPipelineCount getPipelineCount() const; - private: const DxvkDevice* m_device; Rc m_cache; + Rc m_stateCache; std::atomic m_numComputePipelines = { 0 }; std::atomic m_numGraphicsPipelines = { 0 };