From a0239cb75648e96267f8df2a9352cae3d0e2d0f1 Mon Sep 17 00:00:00 2001 From: Samuliak Date: Thu, 9 Jan 2025 16:27:45 +0100 Subject: [PATCH] check for framebuffer fetch support --- .../LatteDecompilerEmitMSL.cpp | 31 ++++++++++--------- .../LatteDecompilerEmitMSLHeader.hpp | 24 +++++++------- .../HW/Latte/Renderer/Metal/MetalRenderer.cpp | 26 +++++++++------- .../HW/Latte/Renderer/Metal/MetalRenderer.h | 6 ++++ 4 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp index 22c511ba..a9e3184c 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp @@ -10,7 +10,7 @@ #include "Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInstructions.h" #include "Cafe/HW/Latte/Core/FetchShader.h" #include "Cafe/HW/Latte/Renderer/Renderer.h" -#include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h" +#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h" #include "Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h" #include "config/ActiveSettings.h" #include "util/helpers/StringBuf.h" @@ -2261,19 +2261,22 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex } // Do a framebuffer fetch if possible - // TODO: filter out more? - uint8 renderTargetIndex = shaderContext->shader->textureRenderTargetIndex[texInstruction->textureFetch.textureIndex]; - if (renderTargetIndex != 255) + if (static_cast(g_renderer.get())->SupportsFramebufferFetch()) { - src->addFmt("col{}.", renderTargetIndex); - // TODO: clean up - std::string components[] = {"x", "y", "z", "w"}; - for (sint32 i = 0; i < numWrittenElements; i++) - { - src->addFmt("{}", components[i]); - } - src->add(");" _CRLF); - return; + // TODO: filter out more? + uint8 renderTargetIndex = shaderContext->shader->textureRenderTargetIndex[texInstruction->textureFetch.textureIndex]; + if (renderTargetIndex != 255) + { + src->addFmt("col{}.", renderTargetIndex); + // TODO: clean up + std::string components[] = {"x", "y", "z", "w"}; + for (sint32 i = 0; i < numWrittenElements; i++) + { + src->addFmt("{}", components[i]); + } + src->add(");" _CRLF); + return; + } } if (emulateCompare) @@ -2646,7 +2649,7 @@ static void _emitTEXGetTextureResInfoCode(LatteDecompilerShaderContext* shaderCo // todo - mip index parameter? - if (shaderContext->shader->textureRenderTargetIndex[texInstruction->textureFetch.textureIndex] != 255) + if (static_cast(g_renderer.get())->SupportsFramebufferFetch() && shaderContext->shader->textureRenderTargetIndex[texInstruction->textureFetch.textureIndex] != 255) { // TODO: use the render target size src->addFmt(" = int4(1920, 1080, 1, 1)."); diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp index 40e70455..84722a24 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp @@ -1,7 +1,7 @@ #pragma once #include "Common/precompiled.h" -#include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h" +#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h" #include "HW/Latte/Core/LatteShader.h" namespace LatteDecompiler @@ -458,11 +458,19 @@ namespace LatteDecompiler continue; uint8 renderTargetIndex = shaderContext->shader->textureRenderTargetIndex[i]; - if (renderTargetIndex == 255) + if (static_cast(g_renderer.get())->SupportsFramebufferFetch() && renderTargetIndex != 255) { - src->add(", "); + if (!renderTargetIndexUsed[renderTargetIndex]) + { + src->addFmt(", {} col{} [[color({})]]", GetDataTypeStr(GetColorBufferDataType(renderTargetIndex, *shaderContext->contextRegistersNew)), renderTargetIndex, renderTargetIndex); + renderTargetIndexUsed[renderTargetIndex] = true; + } + } + else + { + src->add(", "); - // Only 2D and 2D array textures can be used with comparison samplers + // Only certain texture dimensions can be used with comparison samplers if (shaderContext->shader->textureUsesDepthCompare[i] && IsValidDepthTextureType(shaderContext->shader->textureUnitDim[i])) src->add("depth"); else @@ -499,14 +507,6 @@ namespace LatteDecompiler src->addFmt(" tex{} [[texture({})]]", i, binding); src->addFmt(", sampler samplr{} [[sampler({})]]", i, binding); } - else - { - if (!renderTargetIndexUsed[renderTargetIndex]) - { - src->addFmt(", {} col{} [[color({})]]", GetDataTypeStr(GetColorBufferDataType(renderTargetIndex, *shaderContext->contextRegistersNew)), renderTargetIndex, renderTargetIndex); - renderTargetIndexUsed[renderTargetIndex] = true; - } - } } } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index 6bb7964c..bd6f9315 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -87,6 +87,7 @@ MetalRenderer::MetalRenderer() // Feature support m_isAppleGPU = m_device->supportsFamily(MTL::GPUFamilyApple1); + m_supportsFramebufferFetch = m_device->supportsFamily(MTL::GPUFamilyApple2); m_hasUnifiedMemory = m_device->hasUnifiedMemory(); m_supportsMetal3 = m_device->supportsFamily(MTL::GPUFamilyMetal3); m_recommendedMaxVRAMUsage = m_device->recommendedMaxWorkingSetSize(); @@ -584,21 +585,22 @@ void MetalRenderer::DeleteFontTextures() void MetalRenderer::AppendOverlayDebugInfo() { ImGui::Text("--- GPU info ---"); - ImGui::Text("GPU %s", m_device->name()->utf8String()); - ImGui::Text("Is Apple GPU %s", (m_isAppleGPU ? "yes" : "no")); - ImGui::Text("Has unified memory %s", (m_hasUnifiedMemory ? "yes" : "no")); - ImGui::Text("Supports Metal3 %s", (m_supportsMetal3 ? "yes" : "no")); + ImGui::Text("GPU %s", m_device->name()->utf8String()); + ImGui::Text("Is Apple GPU %s", (m_isAppleGPU ? "yes" : "no")); + ImGui::Text("Supports framebuffer fetch %s", (m_supportsFramebufferFetch ? "yes" : "no")); + ImGui::Text("Has unified memory %s", (m_hasUnifiedMemory ? "yes" : "no")); + ImGui::Text("Supports Metal3 %s", (m_supportsMetal3 ? "yes" : "no")); ImGui::Text("--- Metal info ---"); - ImGui::Text("Render pipeline states %zu", m_pipelineCache->GetPipelineCacheSize()); - ImGui::Text("Buffer allocator memory %zuMB", m_performanceMonitor.m_bufferAllocatorMemory / 1024 / 1024); + ImGui::Text("Render pipeline states %zu", m_pipelineCache->GetPipelineCacheSize()); + ImGui::Text("Buffer allocator memory %zuMB", m_performanceMonitor.m_bufferAllocatorMemory / 1024 / 1024); ImGui::Text("--- Metal info (per frame) ---"); - ImGui::Text("Command buffers %u", m_performanceMonitor.m_commandBuffers); - ImGui::Text("Render passes %u", m_performanceMonitor.m_renderPasses); - ImGui::Text("Clears %u", m_performanceMonitor.m_clears); - ImGui::Text("Manual vertex fetch draws %u (mesh draws: %u)", m_performanceMonitor.m_manualVertexFetchDraws, m_performanceMonitor.m_meshDraws); - ImGui::Text("Triangle fans %u", m_performanceMonitor.m_triangleFans); + ImGui::Text("Command buffers %u", m_performanceMonitor.m_commandBuffers); + ImGui::Text("Render passes %u", m_performanceMonitor.m_renderPasses); + ImGui::Text("Clears %u", m_performanceMonitor.m_clears); + ImGui::Text("Manual vertex fetch draws %u (mesh draws: %u)", m_performanceMonitor.m_manualVertexFetchDraws, m_performanceMonitor.m_meshDraws); + ImGui::Text("Triangle fans %u", m_performanceMonitor.m_triangleFans); } void MetalRenderer::renderTarget_setViewport(float x, float y, float width, float height, float nearZ, float farZ, bool halfZ) @@ -1932,7 +1934,7 @@ void MetalRenderer::BindStageResources(MTL::RenderCommandEncoder* renderCommandE auto hostTextureUnit = relative_textureUnit; // Don't bind textures that are accessed with a framebuffer fetch - if (shader->textureRenderTargetIndex[relative_textureUnit] != 255) + if (m_supportsFramebufferFetch && shader->textureRenderTargetIndex[relative_textureUnit] != 255) continue; auto textureDim = shader->textureUnitDim[relative_textureUnit]; diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h index 60fb8e03..db79471d 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h @@ -375,6 +375,11 @@ public: return m_isAppleGPU; } + bool SupportsFramebufferFetch() const + { + return m_supportsFramebufferFetch; + } + bool HasUnifiedMemory() const { return m_hasUnifiedMemory; @@ -477,6 +482,7 @@ private: // Feature support bool m_isAppleGPU; + bool m_supportsFramebufferFetch; bool m_hasUnifiedMemory; bool m_supportsMetal3; uint32 m_recommendedMaxVRAMUsage;