From 8a74445a9632935d218c653377d189d607f5b9cb Mon Sep 17 00:00:00 2001 From: Samo Z Date: Wed, 4 Sep 2024 19:05:07 +0200 Subject: [PATCH] don't compile fragment shaders just-in-time --- .../LatteDecompilerEmitMSL.cpp | 12 +-- .../LatteDecompilerEmitMSLHeader.hpp | 6 +- .../HW/Latte/Renderer/Metal/MetalCommon.h | 8 +- .../Renderer/Metal/MetalPipelineCache.cpp | 2 - .../Renderer/Metal/RendererShaderMtl.cpp | 79 ++----------------- .../Latte/Renderer/Metal/RendererShaderMtl.h | 8 -- 6 files changed, 21 insertions(+), 94 deletions(-) diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp index 5dae2131..1d6ab1a4 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp @@ -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(", 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); } diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp index aed7e9f1..5f88f246 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp @@ -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); } } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h index a2ecc7e9..ede0bed6 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h @@ -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) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp index 9a99f138..1842142e 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp @@ -364,7 +364,6 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte auto mtlVertexShader = static_cast(vertexShader->shader); auto mtlPixelShader = static_cast(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(pixelShader->shader); - mtlPixelShader->CompileFragmentFunction(lastUsedFBO); // Render pipeline state MTL::MeshRenderPipelineDescriptor* desc = MTL::MeshRenderPipelineDescriptor::alloc()->init(); diff --git a/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp b/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp index 8905ddee..d343ef45 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp @@ -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(); -} diff --git a/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.h b/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.h index 6ae2b928..0758b0e6 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.h @@ -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 m_binary; - std::string m_mslCode; - - // HACK - bool m_hasError = false; - void Compile(const std::string& mslCode); };