From 14f42fc653a206f6dc4e2e0f311f0abbd368e377 Mon Sep 17 00:00:00 2001 From: Samuliak Date: Sat, 25 Jan 2025 08:59:48 +0100 Subject: [PATCH] create stack scoped helper macro --- .../Latte/Renderer/Metal/LatteTextureMtl.cpp | 3 +- .../HW/Latte/Renderer/Metal/MetalCommon.h | 10 ++-- .../Renderer/Metal/MetalDepthStencilCache.cpp | 10 +--- .../Renderer/Metal/MetalOutputShaderCache.cpp | 3 +- .../Renderer/Metal/MetalPipelineCompiler.cpp | 3 +- .../HW/Latte/Renderer/Metal/MetalRenderer.cpp | 58 ++++++------------- .../HW/Latte/Renderer/Metal/MetalRenderer.h | 4 ++ .../Renderer/Metal/MetalSamplerCache.cpp | 3 +- .../Metal/MetalVoidVertexPipeline.cpp | 6 +- .../Renderer/Metal/RendererShaderMtl.cpp | 3 +- 10 files changed, 39 insertions(+), 64 deletions(-) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.cpp b/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.cpp index 3c0005ef..c5d1f540 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.cpp @@ -7,7 +7,7 @@ LatteTextureMtl::LatteTextureMtl(class MetalRenderer* mtlRenderer, Latte::E_DIM Latte::E_HWTILEMODE tileMode, bool isDepth) : LatteTexture(dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth), m_mtlr(mtlRenderer) { - MTL::TextureDescriptor* desc = MTL::TextureDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::TextureDescriptor* desc = MTL::TextureDescriptor::alloc()->init(); desc->setStorageMode(MTL::StorageModePrivate); //desc->setCpuCacheMode(MTL::CPUCacheModeWriteCombined); @@ -83,7 +83,6 @@ LatteTextureMtl::LatteTextureMtl(class MetalRenderer* mtlRenderer, Latte::E_DIM desc->setUsage(usage); m_texture = mtlRenderer->GetDevice()->newTexture(desc); - desc->release(); } LatteTextureMtl::~LatteTextureMtl() diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h index a03e7cae..e858baf0 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h @@ -50,10 +50,12 @@ inline size_t Align(size_t size, size_t alignment) return (size + alignment - 1) & ~(alignment - 1); } -//inline std::string GetColorAttachmentTypeStr(uint32 index) -//{ -// return "COLOR_ATTACHMENT" + std::to_string(index) + "_TYPE"; -//} +__attribute__((unused)) static inline void ETStackAutoRelease(void* object) +{ + (*(NS::Object**)object)->release(); +} + +#define NS_STACK_SCOPED __attribute__((cleanup(ETStackAutoRelease))) __attribute__((unused)) // Cast from const char* to NS::String* inline NS::String* ToNSString(const char* str) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalDepthStencilCache.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalDepthStencilCache.cpp index a1e4005b..1fe680bb 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalDepthStencilCache.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalDepthStencilCache.cpp @@ -25,7 +25,7 @@ MTL::DepthStencilState* MetalDepthStencilCache::GetDepthStencilState(const Latte auto depthFunc = lcr.DB_DEPTH_CONTROL.get_Z_FUNC(); bool depthWriteEnable = lcr.DB_DEPTH_CONTROL.get_Z_WRITE_ENABLE(); - MTL::DepthStencilDescriptor* desc = MTL::DepthStencilDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::DepthStencilDescriptor* desc = MTL::DepthStencilDescriptor::alloc()->init(); if (depthEnable) { desc->setDepthWriteEnabled(depthWriteEnable); @@ -52,7 +52,7 @@ MTL::DepthStencilState* MetalDepthStencilCache::GetDepthStencilState(const Latte uint32 stencilCompareMaskBack = lcr.DB_STENCILREFMASK_BF.get_STENCILMASK_B(); uint32 stencilWriteMaskBack = lcr.DB_STENCILREFMASK_BF.get_STENCILWRITEMASK_B(); - MTL::StencilDescriptor* frontStencil = MTL::StencilDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::StencilDescriptor* frontStencil = MTL::StencilDescriptor::alloc()->init(); frontStencil->setReadMask(stencilCompareMaskFront); frontStencil->setWriteMask(stencilWriteMaskFront); frontStencil->setStencilCompareFunction(GetMtlCompareFunc(frontStencilFunc)); @@ -61,7 +61,7 @@ MTL::DepthStencilState* MetalDepthStencilCache::GetDepthStencilState(const Latte frontStencil->setDepthStencilPassOperation(GetMtlStencilOp(frontStencilZPass)); desc->setFrontFaceStencil(frontStencil); - MTL::StencilDescriptor* backStencil = MTL::StencilDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::StencilDescriptor* backStencil = MTL::StencilDescriptor::alloc()->init(); if (backStencilEnable) { backStencil->setReadMask(stencilCompareMaskBack); @@ -81,13 +81,9 @@ MTL::DepthStencilState* MetalDepthStencilCache::GetDepthStencilState(const Latte backStencil->setDepthStencilPassOperation(GetMtlStencilOp(frontStencilZPass)); } desc->setBackFaceStencil(backStencil); - - frontStencil->release(); - backStencil->release(); } depthStencilState = m_mtlr->GetDevice()->newDepthStencilState(desc); - desc->release(); return depthStencilState; } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.cpp index 2f4295d4..48cca54f 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.cpp @@ -21,14 +21,13 @@ MTL::RenderPipelineState* MetalOutputShaderCache::GetPipeline(RendererOutputShad auto vertexShaderMtl = static_cast(shader->GetVertexShader())->GetFunction(); auto fragmentShaderMtl = static_cast(shader->GetFragmentShader())->GetFunction(); - auto renderPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init(); + NS_STACK_SCOPED auto renderPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init(); renderPipelineDescriptor->setVertexFunction(vertexShaderMtl); renderPipelineDescriptor->setFragmentFunction(fragmentShaderMtl); renderPipelineDescriptor->colorAttachments()->object(0)->setPixelFormat(usesSRGB ? MTL::PixelFormatBGRA8Unorm_sRGB : MTL::PixelFormatBGRA8Unorm); NS::Error* error = nullptr; renderPipelineState = m_mtlr->GetDevice()->newRenderPipelineState(renderPipelineDescriptor, &error); - renderPipelineDescriptor->release(); if (error) { cemuLog_log(LogType::Force, "error creating output render pipeline state: {}", error->localizedDescription()->utf8String()); diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.cpp index fb92727d..afd63f8b 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCompiler.cpp @@ -413,7 +413,7 @@ void MetalPipelineCompiler::InitFromStateRender(const LatteFetchShader* fetchSha // Vertex descriptor if (!fetchShader->mtlFetchVertexManually) { - MTL::VertexDescriptor* vertexDescriptor = MTL::VertexDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::VertexDescriptor* vertexDescriptor = MTL::VertexDescriptor::alloc()->init(); for (auto& bufferGroup : fetchShader->bufferGroups) { std::optional fetchType; @@ -476,7 +476,6 @@ void MetalPipelineCompiler::InitFromStateRender(const LatteFetchShader* fetchSha } desc->setVertexDescriptor(vertexDescriptor); - vertexDescriptor->release(); } SetFragmentState(desc, lastUsedAttachmentsInfo, activeAttachmentsInfo, m_rasterizationEnabled, lcr); diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index 78c17695..fe595b82 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -21,7 +21,6 @@ #include "Cemu/Logging/CemuLogging.h" #include "Cafe/HW/Latte/Core/FetchShader.h" #include "Cafe/HW/Latte/Core/LatteConst.h" -#include "HW/Latte/Renderer/Metal/MetalBufferAllocator.h" #include "HW/Latte/Renderer/Metal/MetalCommon.h" #include "config/CemuConfig.h" #include "gui/guiWrapper.h" @@ -41,7 +40,7 @@ void LatteDraw_handleSpecialState8_clearAsDepth(); std::vector MetalRenderer::GetDevices() { - auto devices = MTL::CopyAllDevices(); + NS_STACK_SCOPED auto devices = MTL::CopyAllDevices(); std::vector result; result.reserve(devices->count()); for (uint32 i = 0; i < devices->count(); i++) @@ -49,7 +48,6 @@ std::vector MetalRenderer::GetDevices() MTL::Device* device = static_cast(devices->object(i)); result.emplace_back(std::string(device->name()->utf8String()), device->registryID()); } - devices->release(); return result; } @@ -126,7 +124,7 @@ MetalRenderer::MetalRenderer() // If a device is set, try to find it if (hasDeviceSet) { - auto devices = MTL::CopyAllDevices(); + NS_STACK_SCOPED auto devices = MTL::CopyAllDevices(); for (uint32 i = 0; i < devices->count(); i++) { MTL::Device* device = static_cast(devices->object(i)); @@ -136,7 +134,6 @@ MetalRenderer::MetalRenderer() break; } } - devices->release(); } if (!m_device) @@ -167,7 +164,7 @@ MetalRenderer::MetalRenderer() m_event = m_device->newEvent(); // Resources - MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init(); #ifdef CEMU_DEBUG_ASSERT samplerDescriptor->setLabel(GetLabel("Nearest sampler state", samplerDescriptor)); #endif @@ -179,10 +176,9 @@ MetalRenderer::MetalRenderer() samplerDescriptor->setLabel(GetLabel("Linear sampler state", samplerDescriptor)); #endif m_linearSampler = m_device->newSamplerState(samplerDescriptor); - samplerDescriptor->release(); // Null resources - MTL::TextureDescriptor* textureDescriptor = MTL::TextureDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::TextureDescriptor* textureDescriptor = MTL::TextureDescriptor::alloc()->init(); textureDescriptor->setTextureType(MTL::TextureType1D); textureDescriptor->setWidth(1); textureDescriptor->setUsage(MTL::TextureUsageShaderRead); @@ -198,7 +194,6 @@ MetalRenderer::MetalRenderer() #ifdef CEMU_DEBUG_ASSERT m_nullTexture2D->setLabel(GetLabel("Null texture 2D", m_nullTexture2D)); #endif - textureDescriptor->release(); m_memoryManager = new MetalMemoryManager(this); m_outputShaderCache = new MetalOutputShaderCache(this); @@ -233,28 +228,24 @@ MetalRenderer::MetalRenderer() // Create the library NS::Error* error = nullptr; - MTL::Library* utilityLibrary = m_device->newLibrary(ToNSString(utilityShaderSource), nullptr, &error); + NS_STACK_SCOPED MTL::Library* utilityLibrary = m_device->newLibrary(ToNSString(utilityShaderSource), nullptr, &error); if (error) { cemuLog_log(LogType::Force, "failed to create utility library (error: {})", error->localizedDescription()->utf8String()); } // Pipelines - MTL::Function* vertexFullscreenFunction = utilityLibrary->newFunction(ToNSString("vertexFullscreen")); - MTL::Function* fragmentCopyDepthToColorFunction = utilityLibrary->newFunction(ToNSString("fragmentCopyDepthToColor")); + NS_STACK_SCOPED MTL::Function* vertexFullscreenFunction = utilityLibrary->newFunction(ToNSString("vertexFullscreen")); + NS_STACK_SCOPED MTL::Function* fragmentCopyDepthToColorFunction = utilityLibrary->newFunction(ToNSString("fragmentCopyDepthToColor")); m_copyDepthToColorDesc = MTL::RenderPipelineDescriptor::alloc()->init(); m_copyDepthToColorDesc->setVertexFunction(vertexFullscreenFunction); m_copyDepthToColorDesc->setFragmentFunction(fragmentCopyDepthToColorFunction); - vertexFullscreenFunction->release(); - fragmentCopyDepthToColorFunction->release(); // Void vertex pipelines if (m_isAppleGPU) m_copyBufferToBufferPipeline = new MetalVoidVertexPipeline(this, utilityLibrary, "vertexCopyBufferToBuffer"); - utilityLibrary->release(); - // HACK: for some reason, this variable ends up being initialized to some garbage data, even though its declared as bool m_captureFrame = false; m_occlusionQuery.m_lastCommandBuffer = nullptr; m_captureFrame = false; @@ -414,13 +405,12 @@ void MetalRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool padV uint32 bytesPerRow = GetMtlTextureBytesPerRow(texMtl->format, texMtl->isDepth, width); uint32 size = GetMtlTextureBytesPerImage(texMtl->format, texMtl->isDepth, height, bytesPerRow); - // TODO: get a buffer from the memory manager - MTL::Buffer* buffer = m_device->newBuffer(size, MTL::ResourceStorageModeShared); - auto blitCommandEncoder = GetBlitCommandEncoder(); - blitCommandEncoder->copyFromTexture(texMtl->GetTexture(), 0, 0, MTL::Origin(0, 0, 0), MTL::Size(width, height, 1), buffer, 0, bytesPerRow, 0); - uint8* bufferPtr = (uint8*)buffer->contents(); + auto& bufferAllocator = m_memoryManager->GetStagingAllocator(); + auto buffer = bufferAllocator.AllocateBufferMemory(size, 1); + + blitCommandEncoder->copyFromTexture(texMtl->GetTexture(), 0, 0, MTL::Origin(0, 0, 0), MTL::Size(width, height, 1), buffer.mtlBuffer, buffer.bufferOffset, bytesPerRow, 0); bool formatValid = true; std::vector rgb_data; @@ -431,7 +421,7 @@ void MetalRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool padV switch (pixelFormat) { case MTL::PixelFormatRGBA8Unorm: - for (auto ptr = bufferPtr; ptr < bufferPtr + size; ptr += 4) + for (auto ptr = buffer.memPtr; ptr < buffer.memPtr + size; ptr += 4) { rgb_data.emplace_back(*ptr); rgb_data.emplace_back(*(ptr + 1)); @@ -439,7 +429,7 @@ void MetalRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool padV } break; case MTL::PixelFormatRGBA8Unorm_sRGB: - for (auto ptr = bufferPtr; ptr < bufferPtr + size; ptr += 4) + for (auto ptr = buffer.memPtr; ptr < buffer.memPtr + size; ptr += 4) { rgb_data.emplace_back(SRGBComponentToRGB(*ptr)); rgb_data.emplace_back(SRGBComponentToRGB(*(ptr + 1))); @@ -452,8 +442,6 @@ void MetalRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool padV break; } - buffer->release(); - if (formatValid) SaveScreenshot(rgb_data, width, height, !padView); } @@ -470,14 +458,13 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput // Create render pass auto& layer = GetLayer(!padView); - MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init(); auto colorAttachment = renderPassDescriptor->colorAttachments()->object(0); colorAttachment->setTexture(layer.GetDrawable()->texture()); colorAttachment->setLoadAction(clearBackground ? MTL::LoadActionClear : MTL::LoadActionLoad); colorAttachment->setStoreAction(MTL::StoreActionStore); auto renderCommandEncoder = GetTemporaryRenderCommandEncoder(renderPassDescriptor); - renderPassDescriptor->release(); // Get a render pipeline @@ -557,7 +544,7 @@ bool MetalRenderer::ImguiBegin(bool mainWindow) auto& layer = GetLayer(mainWindow); // Render pass descriptor - MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init(); auto colorAttachment = renderPassDescriptor->colorAttachments()->object(0); colorAttachment->setTexture(layer.GetDrawable()->texture()); colorAttachment->setLoadAction(MTL::LoadActionLoad); @@ -570,7 +557,6 @@ bool MetalRenderer::ImguiBegin(bool mainWindow) if (m_encoderType != MetalEncoderType::Render) GetTemporaryRenderCommandEncoder(renderPassDescriptor); - renderPassDescriptor->release(); return true; } @@ -605,7 +591,7 @@ ImTextureID MetalRenderer::GenerateTexture(const std::vector& data, const tmp[(i * 4) + 3] = 0xFF; } - MTL::TextureDescriptor* desc = MTL::TextureDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::TextureDescriptor* desc = MTL::TextureDescriptor::alloc()->init(); desc->setTextureType(MTL::TextureType2D); desc->setPixelFormat(MTL::PixelFormatRGBA8Unorm); desc->setWidth(size.x); @@ -614,7 +600,6 @@ ImTextureID MetalRenderer::GenerateTexture(const std::vector& data, const desc->setUsage(MTL::TextureUsageShaderRead); MTL::Texture* texture = m_device->newTexture(desc); - desc->release(); // TODO: do a GPU copy? texture->replaceRegion(MTL::Region(0, 0, size.x, size.y), 0, 0, tmp.data(), size.x * 4, 0); @@ -768,11 +753,8 @@ void MetalRenderer::texture_loadSlice(LatteTexture* hostTexture, sint32 width, s // Allocate a temporary buffer auto& bufferAllocator = m_memoryManager->GetStagingAllocator(); auto allocation = bufferAllocator.AllocateBufferMemory(compressedImageSize, 1); - bufferAllocator.FlushReservation(allocation); - - // Copy the data to the temporary buffer memcpy(allocation.memPtr, pixelData, compressedImageSize); - //buffer->didModifyRange(NS::Range(allocation.offset, allocation.size)); + bufferAllocator.FlushReservation(allocation); // TODO: specify blit options when copying to a depth stencil texture? // Copy the data from the temporary buffer to the texture @@ -804,7 +786,7 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl auto mtlTexture = static_cast(hostTexture)->GetTexture(); - MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init(); if (clearDepth) { auto depthAttachment = renderPassDescriptor->depthAttachment(); @@ -827,7 +809,6 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl } GetTemporaryRenderCommandEncoder(renderPassDescriptor); - renderPassDescriptor->release(); EndEncoding(); // Debug @@ -2195,7 +2176,7 @@ void MetalRenderer::BindStageResources(MTL::RenderCommandEncoder* renderCommandE void MetalRenderer::ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a) { - MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init(); auto colorAttachment = renderPassDescriptor->colorAttachments()->object(0); colorAttachment->setTexture(mtlTexture); colorAttachment->setClearColor(MTL::ClearColor(r, g, b, a)); @@ -2205,7 +2186,6 @@ void MetalRenderer::ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 s colorAttachment->setLevel(mipIndex); GetTemporaryRenderCommandEncoder(renderPassDescriptor); - renderPassDescriptor->release(); EndEncoding(); // Debug diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h index 2aa68973..9a2b168c 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h @@ -6,6 +6,7 @@ #include "Cafe/HW/Latte/Renderer/Metal/MetalPerformanceMonitor.h" #include "Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.h" #include "Cafe/HW/Latte/Renderer/Metal/MetalAttachmentsInfo.h" +#include "Foundation/NSAutoreleasePool.hpp" enum MetalGeneralShaderType { @@ -527,6 +528,9 @@ private: MTL::CommandBuffer* m_lastCommandBuffer = nullptr; } m_occlusionQuery; + // Autorelease pool + NS::AutoreleasePool* m_autoreleasePool; + // Active objects MetalCommandBuffer m_currentCommandBuffer{}; std::vector m_executingCommandBuffers; diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalSamplerCache.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalSamplerCache.cpp index b7d5a2ec..a4d734ee 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalSamplerCache.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalSamplerCache.cpp @@ -21,7 +21,7 @@ MTL::SamplerState* MetalSamplerCache::GetSamplerState(const LatteContextRegister // Sampler state const _LatteRegisterSetSampler* samplerWords = lcr.SQ_TEX_SAMPLER + samplerIndex; - MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init(); // lod uint32 iMinLOD = samplerWords->WORD1.get_MIN_LOD(); @@ -115,7 +115,6 @@ MTL::SamplerState* MetalSamplerCache::GetSamplerState(const LatteContextRegister } samplerState = m_mtlr->GetDevice()->newSamplerState(samplerDescriptor); - samplerDescriptor->release(); return samplerState; } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalVoidVertexPipeline.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalVoidVertexPipeline.cpp index 6789505c..7e810e67 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalVoidVertexPipeline.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalVoidVertexPipeline.cpp @@ -3,16 +3,14 @@ MetalVoidVertexPipeline::MetalVoidVertexPipeline(class MetalRenderer* mtlRenderer, MTL::Library* library, const std::string& vertexFunctionName) { // Render pipeline state - MTL::Function* vertexFunction = library->newFunction(ToNSString(vertexFunctionName)); + NS_STACK_SCOPED MTL::Function* vertexFunction = library->newFunction(ToNSString(vertexFunctionName)); - MTL::RenderPipelineDescriptor* renderPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init(); + NS_STACK_SCOPED MTL::RenderPipelineDescriptor* renderPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init(); renderPipelineDescriptor->setVertexFunction(vertexFunction); renderPipelineDescriptor->setRasterizationEnabled(false); NS::Error* error = nullptr; m_renderPipelineState = mtlRenderer->GetDevice()->newRenderPipelineState(renderPipelineDescriptor, &error); - renderPipelineDescriptor->release(); - vertexFunction->release(); if (error) { cemuLog_log(LogType::Force, "error creating hybrid render pipeline state: {}", error->localizedDescription()->utf8String()); diff --git a/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp b/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp index 88f436db..7fd38b5e 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.cpp @@ -276,7 +276,7 @@ bool RendererShaderMtl::ShouldCountCompilation() const MTL::Library* RendererShaderMtl::LibraryFromSource() { // Compile from source - MTL::CompileOptions* options = MTL::CompileOptions::alloc()->init(); + NS_STACK_SCOPED MTL::CompileOptions* options = MTL::CompileOptions::alloc()->init(); if (g_current_game_profile->GetFastMath()) options->setFastMathEnabled(true); @@ -288,7 +288,6 @@ MTL::Library* RendererShaderMtl::LibraryFromSource() NS::Error* error = nullptr; MTL::Library* library = m_mtlr->GetDevice()->newLibrary(ToNSString(m_mslCode), options, &error); - options->release(); if (error) { cemuLog_log(LogType::Force, "failed to create library from source: {} -> {}", error->localizedDescription()->utf8String(), m_mslCode.c_str());