fix: memory leaks

This commit is contained in:
Samuliak 2024-08-03 15:26:57 +02:00
parent fe3b84b4a7
commit fa53af54db
5 changed files with 38 additions and 11 deletions

View File

@ -3,6 +3,14 @@
const size_t BUFFER_ALLOCATION_SIZE = 8 * 1024 * 1024; 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) MetalBufferAllocation MetalBufferAllocator::GetBufferAllocation(size_t size, size_t alignment)
{ {
// Align the size // Align the size
@ -55,6 +63,14 @@ MetalBufferAllocation MetalBufferAllocator::GetBufferAllocation(size_t size, siz
return allocation; return allocation;
} }
MetalMemoryManager::~MetalMemoryManager()
{
if (m_bufferCache)
{
m_bufferCache->release();
}
}
void* MetalMemoryManager::GetTextureUploadBuffer(size_t size) void* MetalMemoryManager::GetTextureUploadBuffer(size_t size)
{ {
if (m_textureUploadBuffer.size() < size) if (m_textureUploadBuffer.size() < size)

View File

@ -24,6 +24,7 @@ class MetalBufferAllocator
{ {
public: public:
MetalBufferAllocator(class MetalRenderer* metalRenderer) : m_mtlr{metalRenderer} {} MetalBufferAllocator(class MetalRenderer* metalRenderer) : m_mtlr{metalRenderer} {}
~MetalBufferAllocator();
void ResetTemporaryBuffers() void ResetTemporaryBuffers()
{ {
@ -54,6 +55,7 @@ class MetalMemoryManager
{ {
public: public:
MetalMemoryManager(class MetalRenderer* metalRenderer) : m_mtlr{metalRenderer}, m_bufferAllocator(metalRenderer) {} MetalMemoryManager(class MetalRenderer* metalRenderer) : m_mtlr{metalRenderer}, m_bufferAllocator(metalRenderer) {}
~MetalMemoryManager();
void ResetTemporaryBuffers() void ResetTemporaryBuffers()
{ {

View File

@ -135,9 +135,11 @@ MTL::RenderPipelineState* MetalPipelineCache::GetPipelineState(const LatteFetchS
NS::Error* error = nullptr; NS::Error* error = nullptr;
pipeline = m_mtlr->GetDevice()->newRenderPipelineState(desc, &error); pipeline = m_mtlr->GetDevice()->newRenderPipelineState(desc, &error);
desc->release(); desc->release();
vertexDescriptor->release();
if (error) if (error)
{ {
debug_printf("error creating render pipeline state: %s\n", error->localizedDescription()->utf8String()); debug_printf("error creating render pipeline state: %s\n", error->localizedDescription()->utf8String());
error->release();
return nullptr; return nullptr;
} }

View File

@ -29,6 +29,7 @@ MetalRenderer::MetalRenderer()
MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init(); MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init();
m_nearestSampler = m_device->newSamplerState(samplerDescriptor); m_nearestSampler = m_device->newSamplerState(samplerDescriptor);
samplerDescriptor->release();
m_memoryManager = new MetalMemoryManager(this); m_memoryManager = new MetalMemoryManager(this);
m_pipelineCache = new MetalPipelineCache(this); m_pipelineCache = new MetalPipelineCache(this);
@ -50,6 +51,8 @@ MetalRenderer::~MetalRenderer()
delete m_pipelineCache; delete m_pipelineCache;
delete m_memoryManager; delete m_memoryManager;
m_nearestSampler->release();
m_commandQueue->release(); m_commandQueue->release();
m_device->release(); m_device->release();
} }
@ -81,19 +84,20 @@ void MetalRenderer::InitializeLayer(const Vector2i& size, bool mainWindow)
renderPipelineDescriptor->setFragmentFunction(presentFragmentFunction); renderPipelineDescriptor->setFragmentFunction(presentFragmentFunction);
renderPipelineDescriptor->colorAttachments()->object(0)->setPixelFormat(m_metalLayer->pixelFormat()); renderPipelineDescriptor->colorAttachments()->object(0)->setPixelFormat(m_metalLayer->pixelFormat());
m_presentPipeline = m_device->newRenderPipelineState(renderPipelineDescriptor, &error); m_presentPipeline = m_device->newRenderPipelineState(renderPipelineDescriptor, &error);
renderPipelineDescriptor->release();
presentVertexFunction->release(); presentVertexFunction->release();
presentFragmentFunction->release(); presentFragmentFunction->release();
if (error) if (error)
{ {
debug_printf("failed to create present pipeline (error: %s)\n", error->localizedDescription()->utf8String()); debug_printf("failed to create present pipeline (error: %s)\n", error->localizedDescription()->utf8String());
error->release(); error->release();
throw;
return; return;
} }
} }
void MetalRenderer::Initialize() void MetalRenderer::Initialize()
{ {
Renderer::Initialize();
} }
void MetalRenderer::Shutdown() void MetalRenderer::Shutdown()
@ -177,6 +181,7 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
colorRenderTargets[0] = m_drawable->texture(); 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 // 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); auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, false, false);
renderPassDescriptor->release();
// Draw to Metal layer // Draw to Metal layer
renderCommandEncoder->setRenderPipelineState(m_presentPipeline); renderCommandEncoder->setRenderPipelineState(m_presentPipeline);
@ -409,6 +414,7 @@ void MetalRenderer::texture_clearColorSlice(LatteTexture* hostTexture, sint32 sl
MTL::Texture* colorRenderTargets[8] = {nullptr}; MTL::Texture* colorRenderTargets[8] = {nullptr};
colorRenderTargets[0] = mtlTexture; colorRenderTargets[0] = mtlTexture;
GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, true); GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, true);
renderPassDescriptor->release();
} }
// TODO: use sliceIndex and mipIndex // TODO: use sliceIndex and mipIndex
@ -436,6 +442,7 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl
MTL::Texture* colorRenderTargets[8] = {nullptr}; MTL::Texture* colorRenderTargets[8] = {nullptr};
GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, mtlTexture, true); 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) 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)

View File

@ -14,17 +14,17 @@ RendererShaderMtl::RendererShaderMtl(MetalRenderer* mtlRenderer, ShaderType type
error->release(); error->release();
return; return;
} }
MTL::FunctionDescriptor* desc = MTL::FunctionDescriptor::alloc()->init(); //MTL::FunctionDescriptor* desc = MTL::FunctionDescriptor::alloc()->init();
desc->setName(NS::String::string("main0", NS::ASCIIStringEncoding)); //desc->setName(NS::String::string("main0", NS::ASCIIStringEncoding));
error = nullptr; //error = nullptr;
m_function = library->newFunction(desc, &error); m_function = library->newFunction(NS::String::string("main0", NS::ASCIIStringEncoding));
library->release(); library->release();
if (error) //if (error)
{ //{
printf("failed to create function (error: %s)\n", error->localizedDescription()->utf8String()); // printf("failed to create function (error: %s)\n", error->localizedDescription()->utf8String());
error->release(); // error->release();
return; // return;
} //}
} }
RendererShaderMtl::~RendererShaderMtl() RendererShaderMtl::~RendererShaderMtl()