do safety checks before clearing

This commit is contained in:
Samuliak 2024-12-14 11:00:42 +01:00
parent 74a1162a17
commit 137becb894
No known key found for this signature in database
4 changed files with 20 additions and 5 deletions

View File

@ -551,7 +551,6 @@ namespace LatteDecompiler
{
bool isRectVertexShader = (static_cast<LattePrimitiveMode>(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
}

View File

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

View File

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

View File

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