diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.cpp index 33d1ee7f..ee01f04b 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.cpp @@ -10,6 +10,8 @@ #include "Cafe/HW/Latte/ISA/RegDefines.h" #include "Cafe/HW/Latte/Core/LatteConst.h" #include "Cafe/HW/Latte/Core/LatteShader.h" +#include "HW/Latte/LegacyShaderDecompiler/LatteDecompiler.h" +#include "HW/Latte/Renderer/RendererShader.h" #include extern std::atomic_int g_compiling_pipelines; @@ -194,7 +196,7 @@ extern std::atomic_int g_compiled_shaders_total; extern std::atomic_int g_compiled_shaders_async; template -void SetFragmentState(T* desc, const MetalAttachmentsInfo& lastUsedAttachmentsInfo, const MetalAttachmentsInfo& activeAttachmentsInfo, const LatteDecompilerShader* pixelShader, const LatteContextRegister& lcr) +void SetFragmentState(T* desc, const MetalAttachmentsInfo& lastUsedAttachmentsInfo, const MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr) { // Rasterization bool rasterizationEnabled = !lcr.PA_CL_CLIP_CNTL.get_DX_RASTERIZATION_KILL(); @@ -211,16 +213,13 @@ void SetFragmentState(T* desc, const MetalAttachmentsInfo& lastUsedAttachmentsIn if (cullFront && cullBack) rasterizationEnabled = false; - auto pixelShaderMtl = static_cast(pixelShader->shader); - - if (!rasterizationEnabled || !pixelShaderMtl) + // TODO: check if the pixel shader is valid as well? + if (!rasterizationEnabled/* || !pixelShaderMtl*/) { desc->setRasterizationEnabled(false); return; } - desc->setFragmentFunction(pixelShaderMtl->GetFunction()); - // Color attachments const Latte::LATTE_CB_COLOR_CONTROL& colorControlReg = lcr.CB_COLOR_CONTROL; uint32 blendEnableMask = colorControlReg.get_BLEND_MASK(); @@ -310,15 +309,29 @@ MetalPipelineCompiler::~MetalPipelineCompiler() void MetalPipelineCompiler::InitFromState(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* geometryShader, const LatteDecompilerShader* pixelShader, const MetalAttachmentsInfo& lastUsedAttachmentsInfo, const MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr) { + // Shaders + m_vertexShader = static_cast(vertexShader->shader); + if (geometryShader) + { + m_geometryShader = static_cast(geometryShader->shader); + } + else + { + // If there is no geometry shader, it means that we are emulating rects + m_geometryShader = rectsEmulationGS_generate(m_mtlr, vertexShader, lcr); + } + m_pixelShader = static_cast(pixelShader->shader); + + // Check if the pipeline uses a geometry shader const LattePrimitiveMode primitiveMode = static_cast(LatteGPUState.contextRegister[mmVGT_PRIMITIVE_TYPE]); bool isPrimitiveRect = (primitiveMode == Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::RECTS); m_usesGeometryShader = (geometryShader != nullptr || isPrimitiveRect); if (m_usesGeometryShader) - InitFromStateMesh(fetchShader, vertexShader, geometryShader, pixelShader, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr); + InitFromStateMesh(fetchShader, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr); else - InitFromStateRender(fetchShader, vertexShader, pixelShader, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr); + InitFromStateRender(fetchShader, vertexShader, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr); } MTL::RenderPipelineState* MetalPipelineCompiler::Compile(bool forceCompile, bool isRenderThread, bool showInOverlay) @@ -331,6 +344,11 @@ MTL::RenderPipelineState* MetalPipelineCompiler::Compile(bool forceCompile, bool { auto desc = static_cast(m_pipelineDescriptor); + // Shaders + desc->setObjectFunction(m_vertexShader->GetFunction()); + desc->setMeshFunction(m_geometryShader->GetFunction()); + desc->setFragmentFunction(m_pixelShader->GetFunction()); + NS::Error* error = nullptr; #ifdef CEMU_DEBUG_ASSERT desc->setLabel(GetLabel("Mesh render pipeline state", desc)); @@ -341,6 +359,10 @@ MTL::RenderPipelineState* MetalPipelineCompiler::Compile(bool forceCompile, bool { auto desc = static_cast(m_pipelineDescriptor); + // Shaders + desc->setVertexFunction(m_vertexShader->GetFunction()); + desc->setFragmentFunction(m_pixelShader->GetFunction()); + NS::Error* error = nullptr; #ifdef CEMU_DEBUG_ASSERT desc->setLabel(GetLabel("Render pipeline state", desc)); @@ -368,14 +390,10 @@ MTL::RenderPipelineState* MetalPipelineCompiler::Compile(bool forceCompile, bool return pipeline; } -void MetalPipelineCompiler::InitFromStateRender(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* pixelShader, const MetalAttachmentsInfo& lastUsedAttachmentsInfo, const MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr) +void MetalPipelineCompiler::InitFromStateRender(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const MetalAttachmentsInfo& lastUsedAttachmentsInfo, const MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr) { - // Shaders - auto vertexShaderMtl = static_cast(vertexShader->shader); - // Render pipeline state MTL::RenderPipelineDescriptor* desc = MTL::RenderPipelineDescriptor::alloc()->init(); - desc->setVertexFunction(vertexShaderMtl->GetFunction()); // Vertex descriptor if (!fetchShader->mtlFetchVertexManually) @@ -447,7 +465,7 @@ void MetalPipelineCompiler::InitFromStateRender(const LatteFetchShader* fetchSha vertexDescriptor->release(); } - SetFragmentState(desc, lastUsedAttachmentsInfo, activeAttachmentsInfo, pixelShader, lcr); + SetFragmentState(desc, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr); m_pipelineDescriptor = desc; @@ -508,26 +526,12 @@ void MetalPipelineCompiler::InitFromStateRender(const LatteFetchShader* fetchSha */ } -void MetalPipelineCompiler::InitFromStateMesh(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* geometryShader, const LatteDecompilerShader* pixelShader, const MetalAttachmentsInfo& lastUsedAttachmentsInfo, const MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr) +void MetalPipelineCompiler::InitFromStateMesh(const LatteFetchShader* fetchShader, const MetalAttachmentsInfo& lastUsedAttachmentsInfo, const MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr) { - auto objectShaderMtl = static_cast(vertexShader->shader); - RendererShaderMtl* meshShaderMtl; - if (geometryShader) - { - meshShaderMtl = static_cast(geometryShader->shader); - } - else - { - // If there is no geometry shader, it means that we are emulating rects - meshShaderMtl = rectsEmulationGS_generate(m_mtlr, vertexShader, lcr); - } - // Render pipeline state MTL::MeshRenderPipelineDescriptor* desc = MTL::MeshRenderPipelineDescriptor::alloc()->init(); - desc->setObjectFunction(objectShaderMtl->GetFunction()); - desc->setMeshFunction(meshShaderMtl->GetFunction()); - SetFragmentState(desc, lastUsedAttachmentsInfo, activeAttachmentsInfo, pixelShader, lcr); + SetFragmentState(desc, lastUsedAttachmentsInfo, activeAttachmentsInfo, lcr); m_pipelineDescriptor = desc; diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.h index 39a4b8a4..4f0febef 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.h @@ -18,6 +18,9 @@ public: private: class MetalRenderer* m_mtlr; + const class RendererShaderMtl* m_vertexShader; + const class RendererShaderMtl* m_geometryShader; + const class RendererShaderMtl* m_pixelShader; bool m_usesGeometryShader; /* @@ -28,9 +31,9 @@ private: */ NS::Object* m_pipelineDescriptor; - void InitFromStateRender(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* pixelShader, const class MetalAttachmentsInfo& lastUsedAttachmentsInfo, const class MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr); + void InitFromStateRender(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const class MetalAttachmentsInfo& lastUsedAttachmentsInfo, const class MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr); - void InitFromStateMesh(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* geometryShader, const LatteDecompilerShader* pixelShader, const class MetalAttachmentsInfo& lastUsedAttachmentsInfo, const class MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr); + void InitFromStateMesh(const LatteFetchShader* fetchShader, const class MetalAttachmentsInfo& lastUsedAttachmentsInfo, const class MetalAttachmentsInfo& activeAttachmentsInfo, const LatteContextRegister& lcr); //void TryLoadBinaryArchive(); };