create stack scoped helper macro

This commit is contained in:
Samuliak 2025-01-25 08:59:48 +01:00
parent b50b9135a0
commit 14f42fc653
No known key found for this signature in database
10 changed files with 39 additions and 64 deletions

View file

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

View file

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

View file

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

View file

@ -21,14 +21,13 @@ MTL::RenderPipelineState* MetalOutputShaderCache::GetPipeline(RendererOutputShad
auto vertexShaderMtl = static_cast<RendererShaderMtl*>(shader->GetVertexShader())->GetFunction();
auto fragmentShaderMtl = static_cast<RendererShaderMtl*>(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());

View file

@ -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<LatteConst::VertexFetchType2> fetchType;
@ -476,7 +476,6 @@ void MetalPipelineCompiler::InitFromStateRender(const LatteFetchShader* fetchSha
}
desc->setVertexDescriptor(vertexDescriptor);
vertexDescriptor->release();
}
SetFragmentState(desc, lastUsedAttachmentsInfo, activeAttachmentsInfo, m_rasterizationEnabled, lcr);

View file

@ -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::DeviceInfo> MetalRenderer::GetDevices()
{
auto devices = MTL::CopyAllDevices();
NS_STACK_SCOPED auto devices = MTL::CopyAllDevices();
std::vector<MetalRenderer::DeviceInfo> result;
result.reserve(devices->count());
for (uint32 i = 0; i < devices->count(); i++)
@ -49,7 +48,6 @@ std::vector<MetalRenderer::DeviceInfo> MetalRenderer::GetDevices()
MTL::Device* device = static_cast<MTL::Device*>(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<MTL::Device*>(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<uint8> 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<uint8>& 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<uint8>& 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<LatteTextureMtl*>(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

View file

@ -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<MTL::CommandBuffer*> m_executingCommandBuffers;

View file

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

View file

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

View file

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