mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-06 23:11:18 +12:00
prepare for AIR cache
This commit is contained in:
parent
21bc5f247b
commit
1e3a3ef298
4 changed files with 101 additions and 6 deletions
|
@ -2,9 +2,6 @@
|
|||
#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureViewMtl.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h"
|
||||
#include "Common/precompiled.h"
|
||||
#include "Metal/MTLResource.hpp"
|
||||
#include "Metal/MTLTexture.hpp"
|
||||
|
||||
LatteTextureMtl::LatteTextureMtl(class MetalRenderer* mtlRenderer, Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle,
|
||||
Latte::E_HWTILEMODE tileMode, bool isDepth)
|
||||
|
@ -12,7 +9,7 @@ LatteTextureMtl::LatteTextureMtl(class MetalRenderer* mtlRenderer, Latte::E_DIM
|
|||
{
|
||||
MTL::TextureDescriptor* desc = MTL::TextureDescriptor::alloc()->init();
|
||||
desc->setStorageMode(MTL::StorageModePrivate);
|
||||
desc->setCpuCacheMode(MTL::CPUCacheModeWriteCombined);
|
||||
//desc->setCpuCacheMode(MTL::CPUCacheModeWriteCombined);
|
||||
|
||||
sint32 effectiveBaseWidth = width;
|
||||
sint32 effectiveBaseHeight = height;
|
||||
|
|
|
@ -101,3 +101,11 @@ inline bool FormatIsRenderable(Latte::E_GX2SURFFMT format)
|
|||
{
|
||||
return !Latte::IsCompressedFormat(format);
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
inline void executeCommand(fmt::format_string<T...> fmt, T&&... args) {
|
||||
std::string command = fmt::format(fmt, std::forward<T>(args)...);
|
||||
int res = system(command.c_str());
|
||||
if (res != 0)
|
||||
cemuLog_log(LogType::Force, "command \"{}\" failed with exit code {}", command, res);
|
||||
}
|
||||
|
|
|
@ -2,14 +2,21 @@
|
|||
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h"
|
||||
|
||||
//#include "Cemu/FileCache/FileCache.h"
|
||||
//#include "config/ActiveSettings.h"
|
||||
#include "Cemu/FileCache/FileCache.h"
|
||||
#include "config/ActiveSettings.h"
|
||||
#include "Cemu/Logging/CemuLogging.h"
|
||||
#include "Common/precompiled.h"
|
||||
#include "GameProfile/GameProfile.h"
|
||||
#include "util/helpers/helpers.h"
|
||||
|
||||
#define METAL_AIR_CACHE_NAME "Cemu_AIR_cache"
|
||||
#define METAL_AIR_CACHE_PATH "/Volumes/" METAL_AIR_CACHE_NAME
|
||||
#define METAL_AIR_CACHE_SIZE (512 * 1024 * 1024)
|
||||
#define METAL_AIR_CACHE_BLOCK_COUNT (METAL_AIR_CACHE_SIZE / 512)
|
||||
|
||||
static bool s_isLoadingShadersMtl{false};
|
||||
static std::atomic<bool> s_hasRAMFilesystem{false};
|
||||
class FileCache* s_airCache{nullptr};
|
||||
|
||||
extern std::atomic_int g_compiled_shaders_total;
|
||||
extern std::atomic_int g_compiled_shaders_async;
|
||||
|
@ -88,12 +95,44 @@ private:
|
|||
// TODO: find out if it would be possible to cache compiled Metal shaders
|
||||
void RendererShaderMtl::ShaderCacheLoading_begin(uint64 cacheTitleId)
|
||||
{
|
||||
s_isLoadingShadersMtl = true;
|
||||
|
||||
// Open AIR cache
|
||||
if (s_airCache)
|
||||
{
|
||||
delete s_airCache;
|
||||
s_airCache = nullptr;
|
||||
}
|
||||
uint32 airCacheMagic = GeneratePrecompiledCacheId();
|
||||
const std::string cacheFilename = fmt::format("{:016x}_air.bin", cacheTitleId);
|
||||
const fs::path cachePath = ActiveSettings::GetCachePath("shaderCache/precompiled/{}", cacheFilename);
|
||||
s_airCache = FileCache::Open(cachePath, true, airCacheMagic);
|
||||
if (!s_airCache)
|
||||
cemuLog_log(LogType::Force, "Unable to open AIR cache {}", cacheFilename);
|
||||
|
||||
// Maximize shader compilation speed
|
||||
static_cast<MetalRenderer*>(g_renderer.get())->SetShouldMaximizeConcurrentCompilation(true);
|
||||
}
|
||||
|
||||
void RendererShaderMtl::ShaderCacheLoading_end()
|
||||
{
|
||||
s_isLoadingShadersMtl = false;
|
||||
|
||||
// Close the AIR cache
|
||||
if (s_airCache)
|
||||
{
|
||||
delete s_airCache;
|
||||
s_airCache = nullptr;
|
||||
}
|
||||
|
||||
// Close RAM filesystem
|
||||
if (s_hasRAMFilesystem)
|
||||
{
|
||||
executeCommand("diskutil eject {}", METAL_AIR_CACHE_PATH);
|
||||
s_hasRAMFilesystem = false;
|
||||
}
|
||||
|
||||
// Reset shader compilation speed
|
||||
static_cast<MetalRenderer*>(g_renderer.get())->SetShouldMaximizeConcurrentCompilation(false);
|
||||
}
|
||||
|
||||
|
@ -174,6 +213,49 @@ bool RendererShaderMtl::ShouldCountCompilation() const
|
|||
|
||||
void RendererShaderMtl::CompileInternal()
|
||||
{
|
||||
// First, try to retrieve the compiled shader from the AIR cache
|
||||
if (s_isLoadingShadersMtl && (m_isGameShader && !m_isGfxPackShader) && s_airCache)
|
||||
{
|
||||
cemu_assert_debug(m_baseHash != 0);
|
||||
uint64 h1, h2;
|
||||
GenerateShaderPrecompiledCacheFilename(m_type, m_baseHash, m_auxHash, h1, h2);
|
||||
std::vector<uint8> cacheFileData;
|
||||
if (s_airCache->GetFile({ h1, h2 }, cacheFileData))
|
||||
{
|
||||
CompileFromAIR(std::span<uint8>(cacheFileData.data(), cacheFileData.size()));
|
||||
FinishCompilation();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ensure that RAM filesystem exists
|
||||
if (!s_hasRAMFilesystem)
|
||||
{
|
||||
s_hasRAMFilesystem = true;
|
||||
executeCommand("diskutil erasevolume HFS+ {} $(hdiutil attach -nomount ram://{})", METAL_AIR_CACHE_NAME, METAL_AIR_CACHE_BLOCK_COUNT);
|
||||
}
|
||||
|
||||
// The shader is not in the cache, compile it
|
||||
std::string filename = fmt::format("{}_{}", h1, h2);
|
||||
// TODO: store the source
|
||||
executeCommand("xcrun -sdk macosx metal -o {}.ir -c {}.metal", filename, filename);
|
||||
executeCommand("xcrun -sdk macosx metallib -o {}.metallib {}.ir", filename, filename);
|
||||
// TODO: clean up
|
||||
|
||||
// Load from the newly Generated AIR
|
||||
// std::span<uint8> airData = ;
|
||||
//CompileFromAIR(std::span<uint8>((uint8*)cacheFileData.data(), cacheFileData.size() / sizeof(uint8)));
|
||||
FinishCompilation();
|
||||
|
||||
// Store in the cache
|
||||
uint64 h1, h2;
|
||||
GenerateShaderPrecompiledCacheFilename(m_type, m_baseHash, m_auxHash, h1, h2);
|
||||
//s_airCache->AddFile({ h1, h2 }, airData.data(), airData.size());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Compile from source
|
||||
MTL::CompileOptions* options = MTL::CompileOptions::alloc()->init();
|
||||
// TODO: always disable fast math for problematic shaders
|
||||
if (g_current_game_profile->GetFastMath())
|
||||
|
@ -200,6 +282,12 @@ void RendererShaderMtl::CompileInternal()
|
|||
g_compiled_shaders_total++;
|
||||
}
|
||||
|
||||
void RendererShaderMtl::CompileFromAIR(std::span<uint8> data)
|
||||
{
|
||||
// TODO: implement this
|
||||
printf("LOADING SHADER FROM AIR CACHE\n");
|
||||
}
|
||||
|
||||
void RendererShaderMtl::FinishCompilation()
|
||||
{
|
||||
m_mslCode.clear();
|
||||
|
|
|
@ -69,5 +69,7 @@ private:
|
|||
|
||||
void CompileInternal();
|
||||
|
||||
void CompileFromAIR(std::span<uint8> data);
|
||||
|
||||
void FinishCompilation();
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue