mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-12-03 06:24:18 +01:00
store loaded pipelines
This commit is contained in:
parent
cd21d957b3
commit
944cc8be7d
@ -14,6 +14,7 @@
|
|||||||
#include "HW/Latte/ISA/LatteReg.h"
|
#include "HW/Latte/ISA/LatteReg.h"
|
||||||
#include "HW/Latte/Renderer/Metal/LatteToMtl.h"
|
#include "HW/Latte/Renderer/Metal/LatteToMtl.h"
|
||||||
#include "HW/Latte/Renderer/Metal/MetalAttachmentsInfo.h"
|
#include "HW/Latte/Renderer/Metal/MetalAttachmentsInfo.h"
|
||||||
|
#include "Metal/MTLRenderPipeline.hpp"
|
||||||
#include "util/helpers/helpers.h"
|
#include "util/helpers/helpers.h"
|
||||||
#include "config/ActiveSettings.h"
|
#include "config/ActiveSettings.h"
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
@ -49,8 +50,7 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte
|
|||||||
compiler.InitFromState(fetchShader, vertexShader, geometryShader, pixelShader, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr);
|
compiler.InitFromState(fetchShader, vertexShader, geometryShader, pixelShader, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr);
|
||||||
pipeline = compiler.Compile(false, true);
|
pipeline = compiler.Compile(false, true);
|
||||||
|
|
||||||
if (!HasPipelineCached(vertexShader->baseHash, hash))
|
AddCurrentStateToCache(hash);
|
||||||
AddCurrentStateToCache(vertexShader->baseHash, hash);
|
|
||||||
|
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
@ -351,6 +351,7 @@ void MetalPipelineCache::LoadPipelineFromCache(std::span<uint8> fileData)
|
|||||||
|
|
||||||
MetalAttachmentsInfo attachmentsInfo(*lcr, pixelShader);
|
MetalAttachmentsInfo attachmentsInfo(*lcr, pixelShader);
|
||||||
|
|
||||||
|
MTL::RenderPipelineState* pipeline = nullptr;
|
||||||
// compile
|
// compile
|
||||||
{
|
{
|
||||||
MetalPipelineCompiler pp(m_mtlr);
|
MetalPipelineCompiler pp(m_mtlr);
|
||||||
@ -362,15 +363,18 @@ void MetalPipelineCache::LoadPipelineFromCache(std::span<uint8> fileData)
|
|||||||
// s_spinlockSharedInternal.unlock();
|
// s_spinlockSharedInternal.unlock();
|
||||||
// return;
|
// return;
|
||||||
//}
|
//}
|
||||||
pp.Compile(true, true);
|
pipeline = pp.Compile(true, true);
|
||||||
// destroy pp early
|
// destroy pp early
|
||||||
}
|
}
|
||||||
|
|
||||||
// on success, calculate pipeline hash and flag as present in cache
|
// on success, calculate pipeline hash and flag as present in cache
|
||||||
uint64 pipelineBaseHash = vertexShader->baseHash;
|
if (pipeline)
|
||||||
uint64 pipelineStateHash = CalculatePipelineHash(vertexShader->compatibleFetchShader, vertexShader, geometryShader, pixelShader, attachmentsInfo, attachmentsInfo, *lcr);
|
{
|
||||||
m_pipelineIsCachedLock.lock();
|
uint64 pipelineStateHash = CalculatePipelineHash(vertexShader->compatibleFetchShader, vertexShader, geometryShader, pixelShader, attachmentsInfo, attachmentsInfo, *lcr);
|
||||||
m_pipelineIsCached.emplace(pipelineBaseHash, pipelineStateHash);
|
m_pipelineCacheLock.lock();
|
||||||
m_pipelineIsCachedLock.unlock();
|
m_pipelineCache[pipelineStateHash] = pipeline;
|
||||||
|
m_pipelineCacheLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
s_spinlockSharedInternal.lock();
|
s_spinlockSharedInternal.lock();
|
||||||
@ -379,17 +383,10 @@ void MetalPipelineCache::LoadPipelineFromCache(std::span<uint8> fileData)
|
|||||||
s_spinlockSharedInternal.unlock();
|
s_spinlockSharedInternal.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetalPipelineCache::HasPipelineCached(uint64 baseHash, uint64 pipelineStateHash)
|
|
||||||
{
|
|
||||||
PipelineHash ph(baseHash, pipelineStateHash);
|
|
||||||
return m_pipelineIsCached.find(ph) != m_pipelineIsCached.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConcurrentQueue<CachedPipeline*> g_mtlPipelineCachingQueue;
|
ConcurrentQueue<CachedPipeline*> g_mtlPipelineCachingQueue;
|
||||||
|
|
||||||
void MetalPipelineCache::AddCurrentStateToCache(uint64 baseHash, uint64 pipelineStateHash)
|
void MetalPipelineCache::AddCurrentStateToCache(uint64 pipelineStateHash)
|
||||||
{
|
{
|
||||||
m_pipelineIsCached.emplace(baseHash, pipelineStateHash);
|
|
||||||
if (!m_pipelineCacheStoreThread)
|
if (!m_pipelineCacheStoreThread)
|
||||||
{
|
{
|
||||||
m_pipelineCacheStoreThread = new std::thread(&MetalPipelineCache::WorkerThread, this);
|
m_pipelineCacheStoreThread = new std::thread(&MetalPipelineCache::WorkerThread, this);
|
||||||
|
@ -7,29 +7,6 @@
|
|||||||
// TODO: binary archives
|
// TODO: binary archives
|
||||||
class MetalPipelineCache
|
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:
|
public:
|
||||||
static MetalPipelineCache& GetInstance();
|
static MetalPipelineCache& GetInstance();
|
||||||
|
|
||||||
@ -45,13 +22,6 @@ public:
|
|||||||
void LoadPipelineFromCache(std::span<uint8> fileData);
|
void LoadPipelineFromCache(std::span<uint8> fileData);
|
||||||
void Close(); // called on title exit
|
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
|
// Debug
|
||||||
size_t GetPipelineCacheSize() const { return m_pipelineCache.size(); }
|
size_t GetPipelineCacheSize() const { return m_pipelineCache.size(); }
|
||||||
|
|
||||||
@ -59,11 +29,10 @@ private:
|
|||||||
class MetalRenderer* m_mtlr;
|
class MetalRenderer* m_mtlr;
|
||||||
|
|
||||||
std::map<uint64, MTL::RenderPipelineState*> m_pipelineCache;
|
std::map<uint64, MTL::RenderPipelineState*> m_pipelineCache;
|
||||||
|
FSpinlock m_pipelineCacheLock;
|
||||||
|
|
||||||
std::thread* m_pipelineCacheStoreThread;
|
std::thread* m_pipelineCacheStoreThread;
|
||||||
|
|
||||||
std::unordered_set<PipelineHash, PipelineHash::HashFunc> m_pipelineIsCached;
|
|
||||||
FSpinlock m_pipelineIsCachedLock;
|
|
||||||
class FileCache* s_cache;
|
class FileCache* s_cache;
|
||||||
|
|
||||||
std::atomic_uint32_t m_numCompilationThreads{ 0 };
|
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);
|
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();
|
int CompilerThread();
|
||||||
void WorkerThread();
|
void WorkerThread();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user