From 137becb89471dcd81698cca61b1dcd4a09ffdba2 Mon Sep 17 00:00:00 2001 From: Samuliak Date: Sat, 14 Dec 2024 11:00:42 +0100 Subject: [PATCH] do safety checks before clearing --- .../LatteDecompilerAnalyzer.cpp | 1 - .../HW/Latte/Renderer/Metal/LatteTextureMtl.cpp | 2 +- src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h | 5 +++++ .../HW/Latte/Renderer/Metal/MetalRenderer.cpp | 17 ++++++++++++++--- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerAnalyzer.cpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerAnalyzer.cpp index e0b39767..ad0f0817 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerAnalyzer.cpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerAnalyzer.cpp @@ -551,7 +551,6 @@ namespace LatteDecompiler { bool isRectVertexShader = (static_cast(decompilerContext->contextRegisters[mmVGT_PRIMITIVE_TYPE]) == LattePrimitiveMode::RECTS); - // TODO: also check for rect primitive if (decompilerContext->shaderType == LatteConst::ShaderType::Vertex && (decompilerContext->options->usesGeometryShader || isRectVertexShader)) decompilerContext->hasUniformVarBlock = true; // uf_verticesPerInstance } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.cpp b/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.cpp index aedd5a3e..a64a2f26 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.cpp @@ -81,7 +81,7 @@ LatteTextureMtl::LatteTextureMtl(class MetalRenderer* mtlRenderer, Latte::E_DIM desc->setPixelFormat(pixelFormat); MTL::TextureUsage usage = MTL::TextureUsageShaderRead | MTL::TextureUsagePixelFormatView; - if (!Latte::IsCompressedFormat(format)) + if (FormatIsRenderable(format)) usage |= MTL::TextureUsageRenderTarget; desc->setUsage(usage); diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h index 20fd6b9d..ba9ebc36 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h @@ -84,3 +84,8 @@ inline bool CommandBufferCompleted(MTL::CommandBuffer* commandBuffer) auto status = commandBuffer->status(); return (status == MTL::CommandBufferStatusCompleted || status == MTL::CommandBufferStatusError); } + +inline bool FormatIsRenderable(Latte::E_GX2SURFFMT format) +{ + return !Latte::IsCompressedFormat(format); +} diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index 82bf4d4b..23b65e67 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -634,6 +634,12 @@ void MetalRenderer::texture_loadSlice(LatteTexture* hostTexture, sint32 width, s void MetalRenderer::texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a) { + if (!FormatIsRenderable(hostTexture->format)) + { + cemuLog_logOnce(LogType::Force, "cannot clear texture with pixel format {}, because it's not renderable", hostTexture->format); + return; + } + auto mtlTexture = static_cast(hostTexture)->GetTexture(); ClearColorTextureInternal(mtlTexture, sliceIndex, mipIndex, r, g, b, a); @@ -641,6 +647,13 @@ void MetalRenderer::texture_clearColorSlice(LatteTexture* hostTexture, sint32 sl void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sliceIndex, sint32 mipIndex, bool clearDepth, bool clearStencil, float depthValue, uint32 stencilValue) { + clearStencil = (clearStencil && GetMtlPixelFormatInfo(hostTexture->format, true).hasStencil); + if (!clearDepth && !clearStencil) + { + cemuLog_logOnce(LogType::Force, "skipping depth/stencil clear"); + return; + } + auto mtlTexture = static_cast(hostTexture)->GetTexture(); MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init(); @@ -654,7 +667,7 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl depthAttachment->setSlice(sliceIndex); depthAttachment->setLevel(mipIndex); } - if (clearStencil && GetMtlPixelFormatInfo(hostTexture->format, true).hasStencil) + if (clearStencil) { auto stencilAttachment = renderPassDescriptor->stencilAttachment(); stencilAttachment->setTexture(mtlTexture); @@ -2046,8 +2059,6 @@ void MetalRenderer::ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 s colorAttachment->setSlice(sliceIndex); colorAttachment->setLevel(mipIndex); - MTL::Texture* colorRenderTargets[8] = {nullptr}; - colorRenderTargets[0] = mtlTexture; GetTemporaryRenderCommandEncoder(renderPassDescriptor); renderPassDescriptor->release(); EndEncoding();