clean up clear attachment code

This commit is contained in:
Samuliak 2024-07-06 21:47:56 +02:00
parent 498c4daed8
commit e33339b655

View file

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