diff --git a/include/renderer_mtl/renderer_mtl.hpp b/include/renderer_mtl/renderer_mtl.hpp index 6de5c7d9..58ec6bae 100644 --- a/include/renderer_mtl/renderer_mtl.hpp +++ b/include/renderer_mtl/renderer_mtl.hpp @@ -124,109 +124,60 @@ class RendererMTL final : public Renderer { } } - void clearColor(MTL::RenderPassDescriptor* renderPassDescriptor, Metal::ColorClearOp clearOp) { + template<typename AttachmentT, typename ClearOpT, typename GetAttachmentT, typename SetClearDataT> + inline void clearAttachment(MTL::RenderPassDescriptor* renderPassDescriptor, ClearOpT clearOp, GetAttachmentT getAttachment, SetClearDataT setClearData) { bool beginRenderPass = (renderPassDescriptor == nullptr); if (!renderPassDescriptor) { renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init(); } - MTL::RenderPassColorAttachmentDescriptor* colorAttachment = renderPassDescriptor->colorAttachments()->object(0); - colorAttachment->setTexture(clearOp.texture); - colorAttachment->setClearColor(MTL::ClearColor(clearOp.r, clearOp.g, clearOp.b, clearOp.a)); - colorAttachment->setLoadAction(MTL::LoadActionClear); - colorAttachment->setStoreAction(MTL::StoreActionStore); + + AttachmentT* attachment = getAttachment(); + attachment->setTexture(clearOp.texture); + setClearData(attachment, clearOp); + attachment->setLoadAction(MTL::LoadActionClear); + attachment->setStoreAction(MTL::StoreActionStore); if (beginRenderPass) { beginRenderPassIfNeeded(renderPassDescriptor, true, clearOp.texture); } } - bool clearColor(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* texture) { - for (int32_t i = colorClearOps.size() - 1; i >= 0; i--) { - if (colorClearOps[i].texture == texture) { - clearColor(renderPassDescriptor, colorClearOps[i]); - colorClearOps.erase(colorClearOps.begin() + i); + template<typename AttachmentT, typename ClearOpT, typename GetAttachmentT, typename SetClearDataT> + inline bool clearAttachment(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* texture, std::vector<ClearOpT>& clearOps, GetAttachmentT getAttachment, SetClearDataT setClearData) { + for (int32_t i = clearOps.size() - 1; i >= 0; i--) { + if (clearOps[i].texture == texture) { + clearAttachment<AttachmentT>(renderPassDescriptor, clearOps[i], getAttachment, setClearData); + clearOps.erase(clearOps.begin() + i); return true; } } if (renderPassDescriptor) { - MTL::RenderPassColorAttachmentDescriptor* colorAttachment = renderPassDescriptor->colorAttachments()->object(0); - colorAttachment->setTexture(texture); - colorAttachment->setLoadAction(MTL::LoadActionLoad); - colorAttachment->setStoreAction(MTL::StoreActionStore); + AttachmentT* attachment = getAttachment(); + attachment->setTexture(texture); + attachment->setLoadAction(MTL::LoadActionLoad); + attachment->setStoreAction(MTL::StoreActionStore); } return false; } - void clearDepth(MTL::RenderPassDescriptor* renderPassDescriptor, Metal::DepthClearOp clearOp) { - bool beginRenderPass = (renderPassDescriptor == nullptr); - if (!renderPassDescriptor) { - renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init(); - } - MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = renderPassDescriptor->depthAttachment(); - depthAttachment->setTexture(clearOp.texture); - depthAttachment->setClearDepth(clearOp.depth); - depthAttachment->setLoadAction(MTL::LoadActionClear); - depthAttachment->setStoreAction(MTL::StoreActionStore); - - if (beginRenderPass) { - beginRenderPassIfNeeded(renderPassDescriptor, true, nullptr, clearOp.texture); - } + bool clearColor(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* texture) { + return clearAttachment<MTL::RenderPassColorAttachmentDescriptor, Metal::ColorClearOp>(renderPassDescriptor, texture, colorClearOps, [&]() { return renderPassDescriptor->colorAttachments()->object(0); }, [&](auto attachment, auto& clearOp) { + attachment->setClearColor(MTL::ClearColor(clearOp.r, clearOp.g, clearOp.b, clearOp.a)); + }); } bool clearDepth(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* texture) { - for (int32_t i = depthClearOps.size() - 1; i >= 0; i--) { - if (depthClearOps[i].texture == texture) { - clearDepth(renderPassDescriptor, depthClearOps[i]); - depthClearOps.erase(depthClearOps.begin() + i); - return true; - } - } - - if (renderPassDescriptor) { - MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = renderPassDescriptor->depthAttachment(); - depthAttachment->setTexture(texture); - depthAttachment->setLoadAction(MTL::LoadActionLoad); - depthAttachment->setStoreAction(MTL::StoreActionStore); - } - - return false; - } - - void clearStencil(MTL::RenderPassDescriptor* renderPassDescriptor, Metal::StencilClearOp clearOp) { - bool beginRenderPass = (renderPassDescriptor == nullptr); - if (!renderPassDescriptor) { - renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init(); - } - MTL::RenderPassStencilAttachmentDescriptor* stencilAttachment = renderPassDescriptor->stencilAttachment(); - stencilAttachment->setTexture(clearOp.texture); - stencilAttachment->setClearStencil(clearOp.stencil); - stencilAttachment->setLoadAction(MTL::LoadActionClear); - stencilAttachment->setStoreAction(MTL::StoreActionStore); - - if (beginRenderPass) { - beginRenderPassIfNeeded(renderPassDescriptor, true, nullptr, clearOp.texture); - } + return clearAttachment<MTL::RenderPassDepthAttachmentDescriptor, Metal::DepthClearOp>(renderPassDescriptor, texture, depthClearOps, [&]() { return renderPassDescriptor->depthAttachment(); }, [&](auto attachment, auto& clearOp) { + attachment->setClearDepth(clearOp.depth); + }); } bool clearStencil(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* texture) { - for (int32_t i = stencilClearOps.size() - 1; i >= 0; i--) { - if (stencilClearOps[i].texture == texture) { - clearStencil(renderPassDescriptor, stencilClearOps[i]); - stencilClearOps.erase(stencilClearOps.begin() + i); - return true; - } - } - - if (renderPassDescriptor) { - MTL::RenderPassStencilAttachmentDescriptor* stencilAttachment = renderPassDescriptor->stencilAttachment(); - stencilAttachment->setTexture(texture); - stencilAttachment->setLoadAction(MTL::LoadActionLoad); - stencilAttachment->setStoreAction(MTL::StoreActionStore); - } - - return false; + return clearAttachment<MTL::RenderPassStencilAttachmentDescriptor, Metal::StencilClearOp>(renderPassDescriptor, texture, stencilClearOps, [&]() { return renderPassDescriptor->stencilAttachment(); }, [&](auto attachment, auto& clearOp) { + attachment->setClearStencil(clearOp.stencil); + }); } std::optional<Metal::ColorRenderTarget> getColorRenderTarget(u32 addr, PICA::ColorFmt format, u32 width, u32 height, bool createIfnotFound = true);