check for framebuffer fetch support

This commit is contained in:
Samuliak 2025-01-09 16:27:45 +01:00
parent 3fae686f21
commit a0239cb756
No known key found for this signature in database
4 changed files with 49 additions and 38 deletions

View file

@ -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,6 +2261,8 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
}
// Do a framebuffer fetch if possible
if (static_cast<MetalRenderer*>(g_renderer.get())->SupportsFramebufferFetch())
{
// TODO: filter out more?
uint8 renderTargetIndex = shaderContext->shader->textureRenderTargetIndex[texInstruction->textureFetch.textureIndex];
if (renderTargetIndex != 255)
@ -2275,6 +2277,7 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
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<MetalRenderer*>(g_renderer.get())->SupportsFramebufferFetch() && shaderContext->shader->textureRenderTargetIndex[texInstruction->textureFetch.textureIndex] != 255)
{
// TODO: use the render target size
src->addFmt(" = int4(1920, 1080, 1, 1).");

View file

@ -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<MetalRenderer*>(g_renderer.get())->SupportsFramebufferFetch() && renderTargetIndex != 255)
{
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;
}
}
}
}

View file

@ -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();
@ -586,6 +587,7 @@ 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("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"));
@ -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];

View file

@ -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;