Skip to content

Commit

Permalink
prepare for shader cache
Browse files Browse the repository at this point in the history
  • Loading branch information
SamoZ256 committed Aug 14, 2024
1 parent 13834ca commit 53efb9e
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 11 deletions.
13 changes: 6 additions & 7 deletions src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -665,22 +665,21 @@ void MetalRenderer::draw_beginSequence()

if (!rasterizerEnable == false)
m_state.m_skipDrawSequence = true;

// TODO: is this even needed?
if (!m_state.m_activeFBO)
m_state.m_skipDrawSequence = true;
}

void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, bool isFirst)
{
//if (m_state.skipDrawSequence)
// TODO: uncomment
//if (m_state.m_skipDrawSequence)
//{
// return;
//}

// Render pass
if (!m_state.m_activeFBO)
{
debug_printf("no active FBO, skipping draw\n");
return;
}

auto renderCommandEncoder = GetRenderCommandEncoder();

// Shaders
Expand Down
68 changes: 64 additions & 4 deletions src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,40 @@
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
#include "Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h"
#include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h"
#include "Cemu/FileCache/FileCache.h"
#include "config/ActiveSettings.h"

#include "Cemu/Logging/CemuLogging.h"
#include "Common/precompiled.h"

bool s_isLoadingShadersMtl{ false };
class FileCache* s_mslCache{nullptr};

extern std::atomic_int g_compiled_shaders_total;
extern std::atomic_int g_compiled_shaders_async;

RendererShaderMtl::RendererShaderMtl(MetalRenderer* mtlRenderer, ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, const std::string& mslCode)
: RendererShader(type, baseHash, auxHash, isGameShader, isGfxPackShader), m_mtlr{mtlRenderer}
{
// Fragment functions are compiled just-in-time
if (LoadBinary())
return;

if (m_type == ShaderType::kFragment)
{
// Fragment functions are compiled just-in-time
m_mslCode = mslCode;
}
else
{
Compile(mslCode);
}

// Store the compiled shader in the cache
StoreBinary();

// Count shader compilation
if (!s_isLoadingShadersMtl)
g_compiled_shaders_total++;
}

RendererShaderMtl::~RendererShaderMtl()
Expand Down Expand Up @@ -69,17 +87,29 @@ void RendererShaderMtl::CompileFragmentFunction(CachedFBOMtl* activeFBO)

void RendererShaderMtl::ShaderCacheLoading_begin(uint64 cacheTitleId)
{
cemuLog_log(LogType::MetalLogging, "RendererShaderMtl::ShaderCacheLoading_begin not implemented!");
if (s_mslCache)
{
delete s_mslCache;
}
uint32 spirvCacheMagic = GeneratePrecompiledCacheId();
const std::string cacheFilename = fmt::format("{:016x}_msl.bin", cacheTitleId);
const fs::path cachePath = ActiveSettings::GetCachePath("shaderCache/precompiled/{}", cacheFilename);
s_mslCache = FileCache::Open(cachePath, true, spirvCacheMagic);
if (!s_mslCache)
cemuLog_log(LogType::Force, "Unable to open MSL cache {}", cacheFilename);
s_isLoadingShadersMtl = true;
}

void RendererShaderMtl::ShaderCacheLoading_end()
{
cemuLog_log(LogType::MetalLogging, "RendererShaderMtl::ShaderCacheLoading_end not implemented!");
s_isLoadingShadersMtl = false;
}

void RendererShaderMtl::ShaderCacheLoading_Close()
{
cemuLog_log(LogType::MetalLogging, "RendererShaderMtl::ShaderCacheLoading_Close not implemented!");
delete s_mslCache;
g_compiled_shaders_total = 0;
g_compiled_shaders_async = 0;
}

void RendererShaderMtl::Compile(const std::string& mslCode)
Expand All @@ -95,3 +125,33 @@ void RendererShaderMtl::Compile(const std::string& mslCode)
m_function = library->newFunction(NS::String::string("main0", NS::ASCIIStringEncoding));
library->release();
}

bool RendererShaderMtl::LoadBinary()
{
// HACK: since fragment functions are compiled just-in-time, we cannot load them from the cache
if (m_type == ShaderType::kFragment)
return false;

uint64 h1, h2;
GenerateShaderPrecompiledCacheFilename(m_type, m_baseHash, m_auxHash, h1, h2);
if (!s_mslCache->GetFile({h1, h2 }, m_binary))
return false;

// TODO: implement
return false;

return true;
}

void RendererShaderMtl::StoreBinary()
{
if (m_binary.size() == 0)
{
// TODO: retrieve the binary from the function
return;
}

uint64 h1, h2;
GenerateShaderPrecompiledCacheFilename(m_type, m_baseHash, m_auxHash, h1, h2);
s_mslCache->AddFileAsync({h1, h2 }, m_binary.data(), m_binary.size());
}
4 changes: 4 additions & 0 deletions src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ class RendererShaderMtl : public RendererShader

MTL::Function* m_function = nullptr;

std::vector<uint8> m_binary;
std::string m_mslCode;

void Compile(const std::string& mslCode);

bool LoadBinary();
void StoreBinary();
};

0 comments on commit 53efb9e

Please sign in to comment.