Cemu/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp
2024-08-14 15:16:10 +02:00

90 lines
2.5 KiB
C++

#include "Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.h"
#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"
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}
{
if (m_type == ShaderType::kFragment)
{
// Fragment functions are compiled just-in-time
m_mslCode = mslCode;
}
else
{
Compile(mslCode);
}
// Count shader compilation
g_compiled_shaders_total++;
}
RendererShaderMtl::~RendererShaderMtl()
{
if (m_function)
m_function->release();
}
void RendererShaderMtl::CompileFragmentFunction(CachedFBOMtl* activeFBO)
{
cemu_assert_debug(m_type == ShaderType::kFragment);
if (m_function)
m_function->release();
std::string fullCode;
// Define color attachment data types
for (uint8 i = 0; i < 8; i++)
{
const auto& colorBuffer = activeFBO->colorBuffer[i];
if (!colorBuffer.texture)
{
continue;
}
auto dataType = GetMtlPixelFormatInfo(colorBuffer.texture->format, false).dataType;
fullCode += "#define " + GetColorAttachmentTypeStr(i) + " ";
switch (dataType)
{
case MetalDataType::INT:
fullCode += "int4";
break;
case MetalDataType::UINT:
fullCode += "uint4";
break;
case MetalDataType::FLOAT:
fullCode += "float4";
break;
default:
cemu_assert_suspicious();
break;
}
fullCode += "\n";
}
fullCode += m_mslCode;
Compile(fullCode);
}
void RendererShaderMtl::Compile(const std::string& mslCode)
{
NS::Error* error = nullptr;
MTL::Library* library = m_mtlr->GetDevice()->newLibrary(NS::String::string(mslCode.c_str(), NS::ASCIIStringEncoding), nullptr, &error);
if (error)
{
printf("failed to create library (error: %s) -> source:\n%s\n", error->localizedDescription()->utf8String(), mslCode.c_str());
error->release();
return;
}
m_function = library->newFunction(NS::String::string("main0", NS::ASCIIStringEncoding));
library->release();
}