diff --git a/src/dxvk/dxvk_framebuffer.cpp b/src/dxvk/dxvk_framebuffer.cpp index 13d37a58..2da9fa86 100644 --- a/src/dxvk/dxvk_framebuffer.cpp +++ b/src/dxvk/dxvk_framebuffer.cpp @@ -4,7 +4,7 @@ namespace dxvk { DxvkFramebuffer::DxvkFramebuffer( const Rc& vkd, - const Rc& renderPass, + DxvkRenderPass* renderPass, const DxvkRenderTargets& renderTargets, const DxvkFramebufferSize& defaultSize) : m_vkd (vkd), diff --git a/src/dxvk/dxvk_framebuffer.h b/src/dxvk/dxvk_framebuffer.h index 49133845..2190a5ae 100644 --- a/src/dxvk/dxvk_framebuffer.h +++ b/src/dxvk/dxvk_framebuffer.h @@ -56,7 +56,7 @@ namespace dxvk { DxvkFramebuffer( const Rc& vkd, - const Rc& renderPass, + DxvkRenderPass* renderPass, const DxvkRenderTargets& renderTargets, const DxvkFramebufferSize& defaultSize); @@ -204,7 +204,7 @@ namespace dxvk { private: const Rc m_vkd; - const Rc m_renderPass; + DxvkRenderPass* m_renderPass; const DxvkRenderTargets m_renderTargets; const DxvkFramebufferSize m_renderSize; diff --git a/src/dxvk/dxvk_renderpass.cpp b/src/dxvk/dxvk_renderpass.cpp index bdab8bbe..4bf4a67a 100644 --- a/src/dxvk/dxvk_renderpass.cpp +++ b/src/dxvk/dxvk_renderpass.cpp @@ -4,7 +4,7 @@ namespace dxvk { - bool DxvkRenderPassFormat::matches(const DxvkRenderPassFormat& fmt) const { + bool DxvkRenderPassFormat::eq(const DxvkRenderPassFormat& fmt) const { bool eq = sampleCount == fmt.sampleCount; for (uint32_t i = 0; i < MaxNumRenderTargets && eq; i++) { @@ -17,6 +17,21 @@ namespace dxvk { return eq; } + + + size_t DxvkRenderPassFormat::hash() const { + DxvkHashState state; + state.add(uint32_t(sampleCount)); + + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + state.add(uint32_t(color[i].format)); + state.add(uint32_t(color[i].layout)); + } + + state.add(uint32_t(depth.format)); + state.add(uint32_t(depth.layout)); + return state; + } DxvkRenderPass::DxvkRenderPass( @@ -39,7 +54,7 @@ namespace dxvk { bool DxvkRenderPass::hasCompatibleFormat(const DxvkRenderPassFormat& fmt) const { - return m_format.matches(fmt); + return m_format.eq(fmt); } @@ -216,17 +231,17 @@ namespace dxvk { } - Rc DxvkRenderPassPool::getRenderPass(const DxvkRenderPassFormat& fmt) { + DxvkRenderPass* DxvkRenderPassPool::getRenderPass(const DxvkRenderPassFormat& fmt) { std::lock_guard lock(m_mutex); + + auto entry = m_renderPasses.find(fmt); + if (entry != m_renderPasses.end()) + return &entry->second; - for (const auto& r : m_renderPasses) { - if (r->hasCompatibleFormat(fmt)) - return r; - } - - Rc rp = new DxvkRenderPass(m_vkd, fmt); - m_renderPasses.push_back(rp); - return rp; + auto result = m_renderPasses.emplace(std::piecewise_construct, + std::tuple(fmt), + std::tuple(m_vkd, fmt)); + return &result.first->second; } } \ No newline at end of file diff --git a/src/dxvk/dxvk_renderpass.h b/src/dxvk/dxvk_renderpass.h index 8c154098..35a1d01f 100644 --- a/src/dxvk/dxvk_renderpass.h +++ b/src/dxvk/dxvk_renderpass.h @@ -32,7 +32,9 @@ namespace dxvk { DxvkAttachmentFormat depth; DxvkAttachmentFormat color[MaxNumRenderTargets]; - bool matches(const DxvkRenderPassFormat& fmt) const; + bool eq(const DxvkRenderPassFormat& fmt) const; + + size_t hash() const; }; @@ -101,7 +103,7 @@ namespace dxvk { * render passes which share the same format but * may differ in their attachment operations. */ - class DxvkRenderPass : public RcObject { + class DxvkRenderPass { public: @@ -211,7 +213,7 @@ namespace dxvk { * \param [in] fmt The render pass format * \returns Matching render pass object */ - Rc getRenderPass( + DxvkRenderPass* getRenderPass( const DxvkRenderPassFormat& fmt); private: @@ -219,7 +221,10 @@ namespace dxvk { const Rc m_vkd; std::mutex m_mutex; - std::vector> m_renderPasses; + std::unordered_map< + DxvkRenderPassFormat, + DxvkRenderPass, + DxvkHash, DxvkEq> m_renderPasses; }; diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 36d1ef85..d45ef1a7 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -135,7 +135,7 @@ namespace dxvk { for (auto e = entries.first; e != entries.second; e++) { const DxvkStateCacheEntry& entry = m_entries[e->second]; - if (entry.format.matches(format) && entry.gpState == state) + if (entry.format.eq(format) && entry.gpState == state) return; }