From 944cc8be7d4f721dad7d3320f3c8eefe87197f17 Mon Sep 17 00:00:00 2001 From: Samuliak Date: Tue, 15 Oct 2024 17:47:47 +0200 Subject: [PATCH] store loaded pipelines --- .../Renderer/Metal/MetalPipelineCache.cpp | 29 +++++++------- .../Latte/Renderer/Metal/MetalPipelineCache.h | 39 ++++--------------- 2 files changed, 20 insertions(+), 48 deletions(-) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp index bb533b7f..910794aa 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp @@ -14,6 +14,7 @@ #include "HW/Latte/ISA/LatteReg.h" #include "HW/Latte/Renderer/Metal/LatteToMtl.h" #include "HW/Latte/Renderer/Metal/MetalAttachmentsInfo.h" +#include "Metal/MTLRenderPipeline.hpp" #include "util/helpers/helpers.h" #include "config/ActiveSettings.h" #include @@ -49,8 +50,7 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte compiler.InitFromState(fetchShader, vertexShader, geometryShader, pixelShader, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr); pipeline = compiler.Compile(false, true); - if (!HasPipelineCached(vertexShader->baseHash, hash)) - AddCurrentStateToCache(vertexShader->baseHash, hash); + AddCurrentStateToCache(hash); return pipeline; } @@ -351,6 +351,7 @@ void MetalPipelineCache::LoadPipelineFromCache(std::span fileData) MetalAttachmentsInfo attachmentsInfo(*lcr, pixelShader); + MTL::RenderPipelineState* pipeline = nullptr; // compile { MetalPipelineCompiler pp(m_mtlr); @@ -362,15 +363,18 @@ void MetalPipelineCache::LoadPipelineFromCache(std::span fileData) // s_spinlockSharedInternal.unlock(); // return; //} - pp.Compile(true, true); + pipeline = pp.Compile(true, true); // destroy pp early } + // on success, calculate pipeline hash and flag as present in cache - uint64 pipelineBaseHash = vertexShader->baseHash; - uint64 pipelineStateHash = CalculatePipelineHash(vertexShader->compatibleFetchShader, vertexShader, geometryShader, pixelShader, attachmentsInfo, attachmentsInfo, *lcr); - m_pipelineIsCachedLock.lock(); - m_pipelineIsCached.emplace(pipelineBaseHash, pipelineStateHash); - m_pipelineIsCachedLock.unlock(); + if (pipeline) + { + uint64 pipelineStateHash = CalculatePipelineHash(vertexShader->compatibleFetchShader, vertexShader, geometryShader, pixelShader, attachmentsInfo, attachmentsInfo, *lcr); + m_pipelineCacheLock.lock(); + m_pipelineCache[pipelineStateHash] = pipeline; + m_pipelineCacheLock.unlock(); + } // clean up s_spinlockSharedInternal.lock(); @@ -379,17 +383,10 @@ void MetalPipelineCache::LoadPipelineFromCache(std::span fileData) s_spinlockSharedInternal.unlock(); } -bool MetalPipelineCache::HasPipelineCached(uint64 baseHash, uint64 pipelineStateHash) -{ - PipelineHash ph(baseHash, pipelineStateHash); - return m_pipelineIsCached.find(ph) != m_pipelineIsCached.end(); -} - ConcurrentQueue g_mtlPipelineCachingQueue; -void MetalPipelineCache::AddCurrentStateToCache(uint64 baseHash, uint64 pipelineStateHash) +void MetalPipelineCache::AddCurrentStateToCache(uint64 pipelineStateHash) { - m_pipelineIsCached.emplace(baseHash, pipelineStateHash); if (!m_pipelineCacheStoreThread) { m_pipelineCacheStoreThread = new std::thread(&MetalPipelineCache::WorkerThread, this); diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.h index d74b5090..be26bdee 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.h @@ -7,29 +7,6 @@ // TODO: binary archives class MetalPipelineCache { -private: - struct PipelineHash - { - PipelineHash(uint64 h0, uint64 h1) : h0(h0), h1(h1) {}; - - uint64 h0; - uint64 h1; - - bool operator==(const PipelineHash& r) const - { - return h0 == r.h0 && h1 == r.h1; - } - - struct HashFunc - { - size_t operator()(const PipelineHash& v) const - { - static_assert(sizeof(uint64) == sizeof(size_t)); - return v.h0 ^ v.h1; - } - }; - }; - public: static MetalPipelineCache& GetInstance(); @@ -45,13 +22,6 @@ public: void LoadPipelineFromCache(std::span fileData); void Close(); // called on title exit - bool HasPipelineCached(uint64 baseHash, uint64 pipelineStateHash); - void AddCurrentStateToCache(uint64 baseHash, uint64 pipelineStateHash); - - // pipeline serialization for file - bool SerializePipeline(class MemStreamWriter& memWriter, struct CachedPipeline& cachedPipeline); - bool DeserializePipeline(class MemStreamReader& memReader, struct CachedPipeline& cachedPipeline); - // Debug size_t GetPipelineCacheSize() const { return m_pipelineCache.size(); } @@ -59,11 +29,10 @@ private: class MetalRenderer* m_mtlr; std::map m_pipelineCache; + FSpinlock m_pipelineCacheLock; std::thread* m_pipelineCacheStoreThread; - std::unordered_set m_pipelineIsCached; - FSpinlock m_pipelineIsCachedLock; class FileCache* s_cache; std::atomic_uint32_t m_numCompilationThreads{ 0 }; @@ -72,6 +41,12 @@ private: static uint64 CalculatePipelineHash(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* geometryShader, const LatteDecompilerShader* pixelShader, const class MetalAttachmentsInfo& lastUsedAttachmentsInfo, const class MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr); + void AddCurrentStateToCache(uint64 pipelineStateHash); + + // pipeline serialization for file + bool SerializePipeline(class MemStreamWriter& memWriter, struct CachedPipeline& cachedPipeline); + bool DeserializePipeline(class MemStreamReader& memReader, struct CachedPipeline& cachedPipeline); + int CompilerThread(); void WorkerThread(); };