From a20032ffb52315832ef5a996da8c7014c4e99c04 Mon Sep 17 00:00:00 2001 From: RedBlackAka <140876408+RedBlackAka@users.noreply.github.com> Date: Wed, 21 Jan 2026 04:46:06 +0100 Subject: [PATCH] Latte/Metal: Exclude more Metal only logic on non-Apple platforms and cleanups (#1781) --- src/Cafe/HW/Latte/Core/FetchShader.cpp | 32 +++++++++++-------- src/Cafe/HW/Latte/Core/FetchShader.h | 2 ++ src/Cafe/HW/Latte/Core/LatteShader.cpp | 8 +++-- .../LatteDecompilerAnalyzer.cpp | 10 ++++-- .../LatteDecompilerInternal.h | 6 ++-- src/gui/wxgui/GeneralSettings2.cpp | 4 +-- src/gui/wxgui/MainWindow.cpp | 2 ++ src/gui/wxgui/PadViewFrame.cpp | 2 ++ 8 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/Cafe/HW/Latte/Core/FetchShader.cpp b/src/Cafe/HW/Latte/Core/FetchShader.cpp index 96b78d83..7d724e13 100644 --- a/src/Cafe/HW/Latte/Core/FetchShader.cpp +++ b/src/Cafe/HW/Latte/Core/FetchShader.cpp @@ -115,22 +115,24 @@ void LatteShader_calculateFSKey(LatteFetchShader* fetchShader) } else { - key += (uint64)(attrib->offset & 3); - key = std::rotl(key, 2); + key += (uint64)(attrib->offset & 3); + key = std::rotl(key, 2); } } } // todo - also hash invalid buffer groups? - if (g_renderer->GetType() == RendererAPI::Metal) - { - for (sint32 g = 0; g < fetchShader->bufferGroups.size(); g++) - { - LatteParsedFetchShaderBufferGroup_t& group = fetchShader->bufferGroups[g]; - key += (uint64)group.attributeBufferIndex; - key = std::rotl(key, 5); - } - } +#if ENABLE_METAL + if (g_renderer->GetType() == RendererAPI::Metal) + { + for (sint32 g = 0; g < fetchShader->bufferGroups.size(); g++) + { + LatteParsedFetchShaderBufferGroup_t& group = fetchShader->bufferGroups[g]; + key += (uint64)group.attributeBufferIndex; + key = std::rotl(key, 5); + } + } +#endif fetchShader->key = key; } @@ -169,9 +171,9 @@ void LatteFetchShader::CalculateFetchShaderVkHash() this->vkPipelineHashFragment = h; } +#if ENABLE_METAL void LatteFetchShader::CheckIfVerticesNeedManualFetchMtl(uint32* contextRegister) { -#if ENABLE_METAL for (sint32 g = 0; g < bufferGroups.size(); g++) { LatteParsedFetchShaderBufferGroup_t& group = bufferGroups[g]; @@ -189,8 +191,8 @@ void LatteFetchShader::CheckIfVerticesNeedManualFetchMtl(uint32* contextRegister mtlFetchVertexManually = true; } } -#endif } +#endif void _fetchShaderDecompiler_parseInstruction_VTX_SEMANTIC(LatteFetchShader* parsedFetchShader, uint32* contextRegister, const LatteClauseInstruction_VTX* instr) { @@ -374,7 +376,9 @@ LatteFetchShader* LatteShaderRecompiler_createFetchShader(LatteFetchShader::Cach // these only make sense when vertex shader does not call FS? LatteShader_calculateFSKey(newFetchShader); newFetchShader->CalculateFetchShaderVkHash(); +#if ENABLE_METAL newFetchShader->CheckIfVerticesNeedManualFetchMtl(contextRegister); +#endif return newFetchShader; } @@ -434,7 +438,9 @@ LatteFetchShader* LatteShaderRecompiler_createFetchShader(LatteFetchShader::Cach } LatteShader_calculateFSKey(newFetchShader); newFetchShader->CalculateFetchShaderVkHash(); +#if ENABLE_METAL newFetchShader->CheckIfVerticesNeedManualFetchMtl(contextRegister); +#endif // register in cache // its possible that during multi-threaded shader cache loading, two identical (same hash) fetch shaders get created simultaneously diff --git a/src/Cafe/HW/Latte/Core/FetchShader.h b/src/Cafe/HW/Latte/Core/FetchShader.h index 1e580f43..54cf6ada 100644 --- a/src/Cafe/HW/Latte/Core/FetchShader.h +++ b/src/Cafe/HW/Latte/Core/FetchShader.h @@ -55,7 +55,9 @@ struct LatteFetchShader void CalculateFetchShaderVkHash(); +#if ENABLE_METAL void CheckIfVerticesNeedManualFetchMtl(uint32* contextRegister); +#endif uint64 getVkPipelineHashFragment() const { return vkPipelineHashFragment; }; diff --git a/src/Cafe/HW/Latte/Core/LatteShader.cpp b/src/Cafe/HW/Latte/Core/LatteShader.cpp index 087643e4..91de6310 100644 --- a/src/Cafe/HW/Latte/Core/LatteShader.cpp +++ b/src/Cafe/HW/Latte/Core/LatteShader.cpp @@ -689,12 +689,14 @@ LatteDecompilerShader* LatteShader_CreateShaderFromDecompilerOutput(LatteDecompi shader->baseHash = baseHash; // copy resource mapping // HACK - if (g_renderer->GetType() == RendererAPI::Vulkan) - shader->resourceMapping = decompilerOutput.resourceMappingVK; - else if (g_renderer->GetType() == RendererAPI::OpenGL) + if (g_renderer->GetType() == RendererAPI::OpenGL) shader->resourceMapping = decompilerOutput.resourceMappingGL; + else if (g_renderer->GetType() == RendererAPI::Vulkan) + shader->resourceMapping = decompilerOutput.resourceMappingVK; +#if ENABLE_METAL else shader->resourceMapping = decompilerOutput.resourceMappingMTL; +#endif // copy texture info shader->textureUnitMask2 = decompilerOutput.textureUnitMask; // copy streamout info diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerAnalyzer.cpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerAnalyzer.cpp index 8eb3c974..18cba4b4 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerAnalyzer.cpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerAnalyzer.cpp @@ -403,9 +403,11 @@ void LatteDecompiler_analyzeExport(LatteDecompilerShaderContext* shaderContext, } else if (cfInstruction->exportType == 0 && cfInstruction->exportArrayBase == 61) { - // Only check for depth buffer mask on Metal, as its not in the PS hash on other backends - if (g_renderer->GetType() != RendererAPI::Metal || LatteMRT::GetActiveDepthBufferMask(*shaderContext->contextRegistersNew)) +#if ENABLE_METAL + // Only check for depth buffer mask on Metal, as its not in the PS hash on other backends + if (g_renderer->GetType() != RendererAPI::Metal || LatteMRT::GetActiveDepthBufferMask(*shaderContext->contextRegistersNew)) shader->depthMask = true; +#endif } else debugBreakpoint(); @@ -510,6 +512,7 @@ namespace LatteDecompiler } } +#if ENABLE_METAL void _initTextureBindingPointsMTL(LatteDecompilerShaderContext* decompilerContext) { // for Vulkan we use consecutive indices @@ -521,6 +524,7 @@ namespace LatteDecompiler decompilerContext->currentTextureBindingPointMTL++; } } +#endif void _initHasUniformVarBlock(LatteDecompilerShaderContext* decompilerContext) { @@ -1109,7 +1113,9 @@ void LatteDecompiler_analyze(LatteDecompilerShaderContext* shaderContext, LatteD shaderContext->output->resourceMappingVK.setIndex = 2; LatteDecompiler::_initTextureBindingPointsGL(shaderContext); LatteDecompiler::_initTextureBindingPointsVK(shaderContext); +#if ENABLE_METAL LatteDecompiler::_initTextureBindingPointsMTL(shaderContext); +#endif LatteDecompiler::_initUniformBindingPoints(shaderContext); LatteDecompiler::_initAttributeBindingPoints(shaderContext); shaderContext->output->resourceMappingMTL.verticesPerInstanceBinding = shaderContext->currentBufferBindingPointMTL++; diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInternal.h b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInternal.h index f4135640..e756ce17 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInternal.h +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInternal.h @@ -117,11 +117,10 @@ struct LatteDecompilerCFInstruction #if BOOST_OS_WINDOWS LatteDecompilerCFInstruction(LatteDecompilerCFInstruction& mE) = default; - LatteDecompilerCFInstruction(LatteDecompilerCFInstruction&& mE) = default; #else LatteDecompilerCFInstruction(const LatteDecompilerCFInstruction& mE) = default; - LatteDecompilerCFInstruction(LatteDecompilerCFInstruction&& mE) = default; #endif + LatteDecompilerCFInstruction(LatteDecompilerCFInstruction&& mE) = default; LatteDecompilerCFInstruction& operator=(LatteDecompilerCFInstruction&& mE) = default; }; @@ -263,6 +262,7 @@ struct LatteDecompilerShaderContext sint32 currentBufferBindingPointMTL{}; sint32 currentTextureBindingPointMTL{}; struct ALUClauseTemporariesState* aluPVPSState{nullptr}; + // misc std::vector list_subroutines; }; @@ -270,7 +270,9 @@ struct LatteDecompilerShaderContext void LatteDecompiler_analyze(LatteDecompilerShaderContext* shaderContext, LatteDecompilerShader* shader); void LatteDecompiler_analyzeDataTypes(LatteDecompilerShaderContext* shaderContext); void LatteDecompiler_emitGLSLShader(LatteDecompilerShaderContext* shaderContext, LatteDecompilerShader* shader); +#if ENABLE_METAL void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, LatteDecompilerShader* shader); +#endif void LatteDecompiler_cleanup(LatteDecompilerShaderContext* shaderContext); diff --git a/src/gui/wxgui/GeneralSettings2.cpp b/src/gui/wxgui/GeneralSettings2.cpp index 3fd3b088..003bd130 100644 --- a/src/gui/wxgui/GeneralSettings2.cpp +++ b/src/gui/wxgui/GeneralSettings2.cpp @@ -1232,21 +1232,21 @@ void GeneralSettings2::StoreConfig() else config.vk_graphic_device_uuid = {}; } +#if ENABLE_METAL else if (config.graphic_api == GraphicAPI::kMetal) { if (selection != wxNOT_FOUND) { -#if ENABLE_METAL const auto* info = (wxMetalUUID*)m_graphic_device->GetClientObject(selection); if (info) config.mtl_graphic_device_uuid = info->GetDeviceInfo().uuid; else config.mtl_graphic_device_uuid = {}; -#endif } else config.mtl_graphic_device_uuid = {}; } +#endif config.gx2drawdone_sync = m_gx2drawdone_sync->IsChecked(); diff --git a/src/gui/wxgui/MainWindow.cpp b/src/gui/wxgui/MainWindow.cpp index b3b978e2..4ef4fe08 100644 --- a/src/gui/wxgui/MainWindow.cpp +++ b/src/gui/wxgui/MainWindow.cpp @@ -13,7 +13,9 @@ #include "AudioDebuggerWindow.h" #include "wxgui/canvas/OpenGLCanvas.h" #include "wxgui/canvas/VulkanCanvas.h" +#if ENABLE_METAL #include "wxgui/canvas/MetalCanvas.h" +#endif #include "Cafe/OS/libs/nfc/nfc.h" #include "Cafe/OS/libs/swkbd/swkbd.h" #include "wxgui/debugger/DebuggerWindow2.h" diff --git a/src/gui/wxgui/PadViewFrame.cpp b/src/gui/wxgui/PadViewFrame.cpp index 8ca46fdd..2079f1eb 100644 --- a/src/gui/wxgui/PadViewFrame.cpp +++ b/src/gui/wxgui/PadViewFrame.cpp @@ -8,7 +8,9 @@ #include "Cafe/OS/libs/swkbd/swkbd.h" #include "wxgui/canvas/OpenGLCanvas.h" #include "wxgui/canvas/VulkanCanvas.h" +#if ENABLE_METAL #include "wxgui/canvas/MetalCanvas.h" +#endif #include "config/CemuConfig.h" #include "wxgui/MainWindow.h" #include "wxgui/helpers/wxHelpers.h"