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,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<MetalRenderer*>(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<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)
{
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;
}
}
}
}

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();
@ -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];

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;