don't compile fragment shaders just-in-time

This commit is contained in:
Samo Z 2024-09-04 19:05:07 +02:00
parent b13ba58aad
commit 8a74445a96
6 changed files with 21 additions and 94 deletions

View File

@ -3215,11 +3215,11 @@ static void _emitExportCode(LatteDecompilerShaderContext* shaderContext, LatteDe
src->add(") == false) discard_fragment();" _CRLF);
}
// pixel color output
src->addFmt("#ifdef {}" _CRLF, GetColorAttachmentTypeStr(pixelColorOutputIndex));
src->addFmt("out.passPixelColor{} = as_type<{}>(", pixelColorOutputIndex, GetColorAttachmentTypeStr(pixelColorOutputIndex));
//src->addFmt("#ifdef {}" _CRLF, GetColorAttachmentTypeStr(pixelColorOutputIndex));
src->addFmt("out.passPixelColor{} = as_type<float4>(", pixelColorOutputIndex/*, GetColorAttachmentTypeStr(pixelColorOutputIndex)*/);
_emitExportGPRReadCode(shaderContext, cfInstruction, LATTE_DECOMPILER_DTYPE_FLOAT, i);
src->add(");" _CRLF);
src->add("#endif" _CRLF);
//src->add("#endif" _CRLF);
if( cfInstruction->exportArrayBase+i >= 8 )
cemu_assert_unimplemented();
@ -3883,12 +3883,12 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
if (shaderContext->options->usesGeometryShader || isRectVertexShader)
{
// TODO: clean this up
// Will modify vid in case of an indexed draw
// fetchVertex will modify vid in case of an indexed draw
// Vertex buffers
std::string vertexBufferDefinitions = "#define VERTEX_BUFFER_DEFINITIONS ";
std::string vertexBuffers = "#define VERTEX_BUFFERS ";
std::string inputFetchDefinition = "VertexIn fetchInput(thread uint& vid, device uint* indexBuffer, uint indexType VERTEX_BUFFER_DEFINITIONS) {\n";
std::string inputFetchDefinition = "VertexIn fetchVertex(thread uint& vid, device uint* indexBuffer, uint indexType VERTEX_BUFFER_DEFINITIONS) {\n";
// Index buffer
inputFetchDefinition += "if (indexType == 1) // UShort\n";
@ -4033,7 +4033,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
// TODO: don't hardcode the instance index
src->add("uint iid = 0;" _CRLF);
// Fetch the input
src->add("VertexIn in = fetchInput(vid, indexBuffer, indexType VERTEX_BUFFERS);" _CRLF);
src->add("VertexIn in = fetchVertex(vid, indexBuffer, indexType VERTEX_BUFFERS);" _CRLF);
// Output is defined as object payload
src->add("object_data VertexOut& out = objectPayload.vertexOut[tid];" _CRLF);
}

View File

@ -281,9 +281,9 @@ namespace LatteDecompiler
{
if ((decompilerContext->shader->pixelColorOutputMask & (1 << i)) != 0)
{
src->addFmt("#ifdef {}" _CRLF, GetColorAttachmentTypeStr(i));
src->addFmt("{} passPixelColor{} [[color({})]];" _CRLF, GetColorAttachmentTypeStr(i), i, i);
src->add("#endif" _CRLF);
//src->addFmt("#ifdef {}" _CRLF, GetColorAttachmentTypeStr(i));
src->addFmt("float4 passPixelColor{} [[color({})]];" _CRLF/*, GetColorAttachmentTypeStr(i)*/, i, i);
//src->add("#endif" _CRLF);
}
}

View File

@ -41,10 +41,10 @@ inline size_t Align(size_t size, size_t alignment)
return (size + alignment - 1) & ~(alignment - 1);
}
inline std::string GetColorAttachmentTypeStr(uint32 index)
{
return "COLOR_ATTACHMENT" + std::to_string(index) + "_TYPE";
}
//inline std::string GetColorAttachmentTypeStr(uint32 index)
//{
// return "COLOR_ATTACHMENT" + std::to_string(index) + "_TYPE";
//}
// Cast from const char* to NS::String*
inline NS::String* ToNSString(const char* str)

View File

@ -364,7 +364,6 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte
auto mtlVertexShader = static_cast<RendererShaderMtl*>(vertexShader->shader);
auto mtlPixelShader = static_cast<RendererShaderMtl*>(pixelShader->shader);
mtlPixelShader->CompileFragmentFunction(lastUsedFBO);
// Render pipeline state
MTL::RenderPipelineDescriptor* desc = MTL::RenderPipelineDescriptor::alloc()->init();
@ -466,7 +465,6 @@ MTL::RenderPipelineState* MetalPipelineCache::GetMeshPipelineState(const LatteFe
mtlMeshShader = rectsEmulationGS_generate(m_mtlr, vertexShader, lcr);
}
auto mtlPixelShader = static_cast<RendererShaderMtl*>(pixelShader->shader);
mtlPixelShader->CompileFragmentFunction(lastUsedFBO);
// Render pipeline state
MTL::MeshRenderPipelineDescriptor* desc = MTL::MeshRenderPipelineDescriptor::alloc()->init();

View File

@ -16,16 +16,16 @@ 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}
{
// TODO: don't compile fragment function just-in-time
if (type != ShaderType::kFragment)
NS::Error* error = nullptr;
MTL::Library* library = m_mtlr->GetDevice()->newLibrary(ToNSString(mslCode), nullptr, &error);
if (error)
{
Compile(mslCode);
}
else
{
// TODO: don't compile just-in-time
m_mslCode = mslCode;
printf("failed to create library (error: %s) -> source:\n%s\n", error->localizedDescription()->utf8String(), mslCode.c_str());
error->release();
return;
}
m_function = library->newFunction(ToNSString("main0"));
library->release();
// Count shader compilation
g_compiled_shaders_total++;
@ -36,66 +36,3 @@ RendererShaderMtl::~RendererShaderMtl()
if (m_function)
m_function->release();
}
void RendererShaderMtl::CompileFragmentFunction(CachedFBOMtl* activeFBO)
{
cemu_assert_debug(m_type == ShaderType::kFragment);
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)
{
if (m_function)
m_function->release();
// HACK
if (m_hasError)
return;
NS::Error* error = nullptr;
MTL::Library* library = m_mtlr->GetDevice()->newLibrary(ToNSString(mslCode), nullptr, &error);
if (error)
{
printf("failed to create library (error: %s) -> source:\n%s\n", error->localizedDescription()->utf8String(), mslCode.c_str());
error->release();
// HACK
m_hasError = true;
return;
}
m_function = library->newFunction(ToNSString("main0"));
library->release();
}

View File

@ -21,8 +21,6 @@ public:
RendererShaderMtl(class MetalRenderer* mtlRenderer, ShaderType type, uint64 baseHash, uint64 auxHash, bool isGameShader, bool isGfxPackShader, const std::string& mslCode);
virtual ~RendererShaderMtl();
void CompileFragmentFunction(CachedFBOMtl* activeFBO);
MTL::Function* GetFunction() const
{
return m_function;
@ -54,11 +52,5 @@ private:
MTL::Function* m_function = nullptr;
std::vector<uint8> m_binary;
std::string m_mslCode;
// HACK
bool m_hasError = false;
void Compile(const std::string& mslCode);
};