mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-20 04:29:13 +12:00
do clears as load ops if possible
This commit is contained in:
parent
2a9da80ff5
commit
498c4daed8
2 changed files with 146 additions and 38 deletions
|
@ -13,6 +13,25 @@
|
|||
|
||||
class GPU;
|
||||
|
||||
namespace Metal {
|
||||
|
||||
struct ColorClearOp {
|
||||
MTL::Texture* texture;
|
||||
float r, g, b, a;
|
||||
};
|
||||
|
||||
struct DepthClearOp {
|
||||
MTL::Texture* texture;
|
||||
float depth;
|
||||
};
|
||||
|
||||
struct StencilClearOp {
|
||||
MTL::Texture* texture;
|
||||
u8 stencil;
|
||||
};
|
||||
|
||||
} // namespace Metal
|
||||
|
||||
class RendererMTL final : public Renderer {
|
||||
public:
|
||||
RendererMTL(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs);
|
||||
|
@ -57,6 +76,11 @@ class RendererMTL final : public Renderer {
|
|||
MTL::RenderPipelineState* displayPipeline;
|
||||
MTL::RenderPipelineState* copyToLutTexturePipeline;
|
||||
|
||||
// Clears
|
||||
std::vector<Metal::ColorClearOp> colorClearOps;
|
||||
std::vector<Metal::DepthClearOp> depthClearOps;
|
||||
std::vector<Metal::StencilClearOp> stencilClearOps;
|
||||
|
||||
// Active state
|
||||
MTL::CommandBuffer* commandBuffer = nullptr;
|
||||
MTL::RenderCommandEncoder* renderCommandEncoder = nullptr;
|
||||
|
@ -76,10 +100,10 @@ class RendererMTL final : public Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
void beginRenderPassIfNeeded(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorTexture, MTL::Texture* depthTexture = nullptr) {
|
||||
void beginRenderPassIfNeeded(MTL::RenderPassDescriptor* renderPassDescriptor, bool doesClears, MTL::Texture* colorTexture, MTL::Texture* depthTexture = nullptr) {
|
||||
createCommandBufferIfNeeded();
|
||||
|
||||
if (!renderCommandEncoder || colorTexture != lastColorTexture || depthTexture != lastDepthTexture) {
|
||||
if (doesClears || !renderCommandEncoder || colorTexture != lastColorTexture || (depthTexture != lastDepthTexture || depthTexture == nullptr)) {
|
||||
endRenderPass();
|
||||
|
||||
renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor);
|
||||
|
@ -100,6 +124,111 @@ class RendererMTL final : public Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
void clearColor(MTL::RenderPassDescriptor* renderPassDescriptor, Metal::ColorClearOp clearOp) {
|
||||
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);
|
||||
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (renderPassDescriptor) {
|
||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
||||
colorAttachment->setTexture(texture);
|
||||
colorAttachment->setLoadAction(MTL::LoadActionLoad);
|
||||
colorAttachment->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 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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
std::optional<Metal::ColorRenderTarget> getColorRenderTarget(u32 addr, PICA::ColorFmt format, u32 width, u32 height, bool createIfnotFound = true);
|
||||
Metal::DepthStencilRenderTarget& getDepthRenderTarget();
|
||||
Metal::Texture& getTexture(Metal::Texture& tex);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue