From fa53af54db1ac05acc952269968a50f586f8fa50 Mon Sep 17 00:00:00 2001 From: Samuliak Date: Sat, 3 Aug 2024 15:26:57 +0200 Subject: [PATCH] fix: memory leaks --- .../Renderer/Metal/MetalMemoryManager.cpp | 16 +++++++++++++++ .../Latte/Renderer/Metal/MetalMemoryManager.h | 2 ++ .../Renderer/Metal/MetalPipelineCache.cpp | 2 ++ .../HW/Latte/Renderer/Metal/MetalRenderer.cpp | 9 ++++++++- .../Renderer/Metal/RendererShaderMtl.cpp | 20 +++++++++---------- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp index 9e615c22..f6f064f3 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp @@ -3,6 +3,14 @@ const size_t BUFFER_ALLOCATION_SIZE = 8 * 1024 * 1024; +MetalBufferAllocator::~MetalBufferAllocator() +{ + for (auto buffer : m_buffers) + { + buffer->release(); + } +} + MetalBufferAllocation MetalBufferAllocator::GetBufferAllocation(size_t size, size_t alignment) { // Align the size @@ -55,6 +63,14 @@ MetalBufferAllocation MetalBufferAllocator::GetBufferAllocation(size_t size, siz return allocation; } +MetalMemoryManager::~MetalMemoryManager() +{ + if (m_bufferCache) + { + m_bufferCache->release(); + } +} + void* MetalMemoryManager::GetTextureUploadBuffer(size_t size) { if (m_textureUploadBuffer.size() < size) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h index 58096eab..b0be2948 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h @@ -24,6 +24,7 @@ class MetalBufferAllocator { public: MetalBufferAllocator(class MetalRenderer* metalRenderer) : m_mtlr{metalRenderer} {} + ~MetalBufferAllocator(); void ResetTemporaryBuffers() { @@ -54,6 +55,7 @@ class MetalMemoryManager { public: MetalMemoryManager(class MetalRenderer* metalRenderer) : m_mtlr{metalRenderer}, m_bufferAllocator(metalRenderer) {} + ~MetalMemoryManager(); void ResetTemporaryBuffers() { diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp index 328fd6d0..d6976a8d 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp @@ -135,9 +135,11 @@ MTL::RenderPipelineState* MetalPipelineCache::GetPipelineState(const LatteFetchS NS::Error* error = nullptr; pipeline = m_mtlr->GetDevice()->newRenderPipelineState(desc, &error); desc->release(); + vertexDescriptor->release(); if (error) { debug_printf("error creating render pipeline state: %s\n", error->localizedDescription()->utf8String()); + error->release(); return nullptr; } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index efc9233a..e99f641c 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -29,6 +29,7 @@ MetalRenderer::MetalRenderer() MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init(); m_nearestSampler = m_device->newSamplerState(samplerDescriptor); + samplerDescriptor->release(); m_memoryManager = new MetalMemoryManager(this); m_pipelineCache = new MetalPipelineCache(this); @@ -50,6 +51,8 @@ MetalRenderer::~MetalRenderer() delete m_pipelineCache; delete m_memoryManager; + m_nearestSampler->release(); + m_commandQueue->release(); m_device->release(); } @@ -81,19 +84,20 @@ void MetalRenderer::InitializeLayer(const Vector2i& size, bool mainWindow) renderPipelineDescriptor->setFragmentFunction(presentFragmentFunction); renderPipelineDescriptor->colorAttachments()->object(0)->setPixelFormat(m_metalLayer->pixelFormat()); m_presentPipeline = m_device->newRenderPipelineState(renderPipelineDescriptor, &error); + renderPipelineDescriptor->release(); presentVertexFunction->release(); presentFragmentFunction->release(); if (error) { debug_printf("failed to create present pipeline (error: %s)\n", error->localizedDescription()->utf8String()); error->release(); - throw; return; } } void MetalRenderer::Initialize() { + Renderer::Initialize(); } void MetalRenderer::Shutdown() @@ -177,6 +181,7 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput colorRenderTargets[0] = m_drawable->texture(); // If there was already an encoder with these attachment, we should set the viewport and scissor to default, but that shouldn't happen auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, false, false); + renderPassDescriptor->release(); // Draw to Metal layer renderCommandEncoder->setRenderPipelineState(m_presentPipeline); @@ -409,6 +414,7 @@ void MetalRenderer::texture_clearColorSlice(LatteTexture* hostTexture, sint32 sl MTL::Texture* colorRenderTargets[8] = {nullptr}; colorRenderTargets[0] = mtlTexture; GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, true); + renderPassDescriptor->release(); } // TODO: use sliceIndex and mipIndex @@ -436,6 +442,7 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl MTL::Texture* colorRenderTargets[8] = {nullptr}; GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, mtlTexture, true); + renderPassDescriptor->release(); } LatteTexture* MetalRenderer::texture_createTextureEx(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle, Latte::E_HWTILEMODE tileMode, bool isDepth) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp b/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp index f0d5fda1..dcceb18a 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp @@ -14,17 +14,17 @@ RendererShaderMtl::RendererShaderMtl(MetalRenderer* mtlRenderer, ShaderType type error->release(); return; } - MTL::FunctionDescriptor* desc = MTL::FunctionDescriptor::alloc()->init(); - desc->setName(NS::String::string("main0", NS::ASCIIStringEncoding)); - error = nullptr; - m_function = library->newFunction(desc, &error); + //MTL::FunctionDescriptor* desc = MTL::FunctionDescriptor::alloc()->init(); + //desc->setName(NS::String::string("main0", NS::ASCIIStringEncoding)); + //error = nullptr; + m_function = library->newFunction(NS::String::string("main0", NS::ASCIIStringEncoding)); library->release(); - if (error) - { - printf("failed to create function (error: %s)\n", error->localizedDescription()->utf8String()); - error->release(); - return; - } + //if (error) + //{ + // printf("failed to create function (error: %s)\n", error->localizedDescription()->utf8String()); + // error->release(); + // return; + //} } RendererShaderMtl::~RendererShaderMtl()