diff --git a/src/dxvk/dxvk_pipemgr.cpp b/src/dxvk/dxvk_pipemgr.cpp index 7457c933..1b7df0d5 100644 --- a/src/dxvk/dxvk_pipemgr.cpp +++ b/src/dxvk/dxvk_pipemgr.cpp @@ -2,15 +2,33 @@ namespace dxvk { - DxvkPipelineManager:: DxvkPipelineManager() { } - DxvkPipelineManager::~DxvkPipelineManager() { } + DxvkPipelineManager::DxvkPipelineManager( + const Rc& vkd) + : m_vkd(vkd) { + TRACE(this); + } + + + DxvkPipelineManager::~DxvkPipelineManager() { + TRACE(this); + } Rc DxvkPipelineManager::getComputePipeline( const Rc& cs) { + DxvkPipelineKey<1> key; + key.setShader(0, cs); + std::lock_guard lock(m_mutex); + auto pair = m_computePipelines.find(key); + if (pair != m_computePipelines.end()) + return pair->second; + + Rc pipeline = new DxvkComputePipeline(m_vkd, cs); + m_computePipelines.insert(std::make_pair(key, pipeline)); + return pipeline; } @@ -21,6 +39,22 @@ namespace dxvk { const Rc& gs, const Rc& fs) { + DxvkPipelineKey<5> key; + key.setShader(0, vs); + key.setShader(1, tcs); + key.setShader(2, tes); + key.setShader(3, gs); + key.setShader(4, fs); + + std::lock_guard lock(m_mutex); + + auto pair = m_graphicsPipelines.find(key); + if (pair != m_graphicsPipelines.end()) + return pair->second; + + Rc pipeline = new DxvkGraphicsPipeline(m_vkd, vs, tcs, tes, gs, fs); + m_graphicsPipelines.insert(std::make_pair(key, pipeline)); + return pipeline; } } \ No newline at end of file diff --git a/src/dxvk/dxvk_pipemgr.h b/src/dxvk/dxvk_pipemgr.h index dd14babb..c625bba8 100644 --- a/src/dxvk/dxvk_pipemgr.h +++ b/src/dxvk/dxvk_pipemgr.h @@ -1,10 +1,57 @@ #pragma once +#include +#include + #include "dxvk_compute.h" +#include "dxvk_hash.h" #include "dxvk_graphics.h" namespace dxvk { + /** + * \brief Pipeline key + * + * Stores a fixed-size set of shaders in order + * to identify a shader pipeline object. + */ + template + class DxvkPipelineKey { + + public: + + void setShader( + size_t id, + const Rc& shader) { + m_shaders.at(id) = shader; + } + + size_t hash() const { + std::hash phash; + + DxvkHashState state; + for (size_t i = 0; i < N; i++) + state.add(phash(m_shaders[i].ptr())); + return state; + } + + bool operator == (const DxvkPipelineKey& other) const { + bool result = true; + for (size_t i = 0; (i < N) && result; i++) + result &= m_shaders[i] == other.m_shaders[i]; + return result; + } + + bool operator != (const DxvkPipelineKey& other) const { + return !this->operator == (other); + } + + private: + + std::array, N> m_shaders; + + }; + /** * \brief Pipeline manager * @@ -15,7 +62,8 @@ namespace dxvk { public: - DxvkPipelineManager(); + DxvkPipelineManager( + const Rc& vkd); ~DxvkPipelineManager(); /** @@ -51,8 +99,20 @@ namespace dxvk { private: + Rc m_vkd; + std::mutex m_mutex; + std::unordered_map< + DxvkPipelineKey<1>, + Rc, + DxvkHash> m_computePipelines; + + std::unordered_map< + DxvkPipelineKey<5>, + Rc, + DxvkHash> m_graphicsPipelines; + }; } \ No newline at end of file