fix: pipeline cache with mesh shaders

This commit is contained in:
Samuliak 2024-10-19 09:29:14 +02:00
parent 8f2385a690
commit 15eb6bb37f
No known key found for this signature in database
3 changed files with 35 additions and 27 deletions

View File

@ -43,19 +43,21 @@ MetalPipelineCache::~MetalPipelineCache()
MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* geometryShader, const LatteDecompilerShader* pixelShader, const MetalAttachmentsInfo& lastUsedAttachmentsInfo, const MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr)
{
uint64 hash = CalculatePipelineHash(fetchShader, vertexShader, geometryShader, pixelShader, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr);
auto& pipeline = m_pipelineCache[hash];
if (pipeline)
return pipeline;
auto it = m_pipelineCache.find(hash);
if (it != m_pipelineCache.end())
return it->second;
MetalPipelineCompiler compiler(m_mtlr);
bool fbosMatch;
compiler.InitFromState(fetchShader, vertexShader, geometryShader, pixelShader, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr, fbosMatch);
pipeline = compiler.Compile(false, true, true);
MTL::RenderPipelineState* pipeline = compiler.Compile(false, true, true);
// If FBOs don't match, it wouldn't be possible to reconstruct the pipeline from the cache
if (fbosMatch)
AddCurrentStateToCache(hash);
m_pipelineCache.insert({hash, pipeline});
return pipeline;
}
@ -355,6 +357,9 @@ void MetalPipelineCache::LoadPipelineFromCache(std::span<uint8> fileData)
MetalAttachmentsInfo attachmentsInfo(*lcr, pixelShader);
// TODO: this shouldn't probably be called directly
LatteShader_UpdatePSInputs(lcr->GetRawView());
MTL::RenderPipelineState* pipeline = nullptr;
// compile
{

View File

@ -10,8 +10,7 @@
#include "Cafe/HW/Latte/ISA/RegDefines.h"
#include "Cafe/HW/Latte/Core/LatteConst.h"
#include "Cafe/HW/Latte/Core/LatteShader.h"
#include "HW/Latte/LegacyShaderDecompiler/LatteDecompiler.h"
#include "HW/Latte/Renderer/RendererShader.h"
#include <chrono>
extern std::atomic_int g_compiling_pipelines;
@ -196,23 +195,8 @@ extern std::atomic_int g_compiled_shaders_total;
extern std::atomic_int g_compiled_shaders_async;
template<typename T>
void SetFragmentState(T* desc, const MetalAttachmentsInfo& lastUsedAttachmentsInfo, const MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr, bool& fbosMatch)
void SetFragmentState(T* desc, const MetalAttachmentsInfo& lastUsedAttachmentsInfo, const MetalAttachmentsInfo& activeAttachmentsInfo, bool rasterizationEnabled, const LatteContextRegister& lcr, bool& fbosMatch)
{
// Rasterization
bool rasterizationEnabled = !lcr.PA_CL_CLIP_CNTL.get_DX_RASTERIZATION_KILL();
// HACK
// TODO: include this in the hash?
if (!lcr.PA_CL_VTE_CNTL.get_VPORT_X_OFFSET_ENA())
rasterizationEnabled = true;
// Culling both front and back faces effectively disables rasterization
const auto& polygonControlReg = lcr.PA_SU_SC_MODE_CNTL;
uint32 cullFront = polygonControlReg.get_CULL_FRONT();
uint32 cullBack = polygonControlReg.get_CULL_BACK();
if (cullFront && cullBack)
rasterizationEnabled = false;
// TODO: check if the pixel shader is valid as well?
if (!rasterizationEnabled/* || !pixelShaderMtl*/)
{
@ -317,6 +301,21 @@ void MetalPipelineCompiler::InitFromState(const LatteFetchShader* fetchShader, c
m_usesGeometryShader = (geometryShader != nullptr || isPrimitiveRect);
// Rasterization
m_rasterizationEnabled = !lcr.PA_CL_CLIP_CNTL.get_DX_RASTERIZATION_KILL();
// HACK
// TODO: include this in the hash?
if (!lcr.PA_CL_VTE_CNTL.get_VPORT_X_OFFSET_ENA())
m_rasterizationEnabled = true;
// Culling both front and back faces effectively disables rasterization
const auto& polygonControlReg = lcr.PA_SU_SC_MODE_CNTL;
uint32 cullFront = polygonControlReg.get_CULL_FRONT();
uint32 cullBack = polygonControlReg.get_CULL_BACK();
if (cullFront && cullBack)
m_rasterizationEnabled = false;
// Shaders
m_vertexShaderMtl = static_cast<RendererShaderMtl*>(vertexShader->shader);
if (geometryShader)
@ -368,7 +367,8 @@ MTL::RenderPipelineState* MetalPipelineCompiler::Compile(bool forceCompile, bool
// Shaders
desc->setObjectFunction(m_vertexShaderMtl->GetFunction());
desc->setMeshFunction(m_geometryShaderMtl->GetFunction());
desc->setFragmentFunction(m_pixelShaderMtl->GetFunction());
if (m_rasterizationEnabled)
desc->setFragmentFunction(m_pixelShaderMtl->GetFunction());
#ifdef CEMU_DEBUG_ASSERT
desc->setLabel(GetLabel("Mesh render pipeline state", desc));
@ -381,7 +381,8 @@ MTL::RenderPipelineState* MetalPipelineCompiler::Compile(bool forceCompile, bool
// Shaders
desc->setVertexFunction(m_vertexShaderMtl->GetFunction());
desc->setFragmentFunction(m_pixelShaderMtl->GetFunction());
if (m_rasterizationEnabled)
desc->setFragmentFunction(m_pixelShaderMtl->GetFunction());
#ifdef CEMU_DEBUG_ASSERT
desc->setLabel(GetLabel("Render pipeline state", desc));
@ -397,7 +398,8 @@ MTL::RenderPipelineState* MetalPipelineCompiler::Compile(bool forceCompile, bool
cemuLog_log(LogType::Force, "error creating render pipeline state: {}", error->localizedDescription()->utf8String());
error->release();
}
else if (showInOverlay)
if (showInOverlay)
{
if (isRenderThread)
g_compiling_pipelines_syncTimeSum += creationDuration;
@ -484,7 +486,7 @@ void MetalPipelineCompiler::InitFromStateRender(const LatteFetchShader* fetchSha
vertexDescriptor->release();
}
SetFragmentState(desc, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr, fbosMatch);
SetFragmentState(desc, lastUsedAttachmentsInfo, activeAttachmentsInfo, m_rasterizationEnabled, lcr, fbosMatch);
m_pipelineDescriptor = desc;
@ -550,7 +552,7 @@ void MetalPipelineCompiler::InitFromStateMesh(const LatteFetchShader* fetchShade
// Render pipeline state
MTL::MeshRenderPipelineDescriptor* desc = MTL::MeshRenderPipelineDescriptor::alloc()->init();
SetFragmentState(desc, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr, fbosMatch);
SetFragmentState(desc, lastUsedAttachmentsInfo, activeAttachmentsInfo, m_rasterizationEnabled, lcr, fbosMatch);
m_pipelineDescriptor = desc;

View File

@ -22,6 +22,7 @@ private:
class RendererShaderMtl* m_geometryShaderMtl;
class RendererShaderMtl* m_pixelShaderMtl;
bool m_usesGeometryShader;
bool m_rasterizationEnabled;
/*
std::map<uint64, MTL::RenderPipelineState*> m_pipelineCache;