mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-03 12:27:21 +12:00
use map instead of vector for clear ops
This commit is contained in:
parent
e33339b655
commit
a9b4f64ca7
2 changed files with 28 additions and 41 deletions
|
@ -13,25 +13,10 @@
|
||||||
|
|
||||||
class GPU;
|
class GPU;
|
||||||
|
|
||||||
namespace Metal {
|
struct Color4 {
|
||||||
|
|
||||||
struct ColorClearOp {
|
|
||||||
MTL::Texture* texture;
|
|
||||||
float r, g, b, a;
|
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 {
|
class RendererMTL final : public Renderer {
|
||||||
public:
|
public:
|
||||||
RendererMTL(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs);
|
RendererMTL(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs);
|
||||||
|
@ -77,9 +62,9 @@ class RendererMTL final : public Renderer {
|
||||||
MTL::RenderPipelineState* copyToLutTexturePipeline;
|
MTL::RenderPipelineState* copyToLutTexturePipeline;
|
||||||
|
|
||||||
// Clears
|
// Clears
|
||||||
std::vector<Metal::ColorClearOp> colorClearOps;
|
std::map<MTL::Texture*, Color4> colorClearOps;
|
||||||
std::vector<Metal::DepthClearOp> depthClearOps;
|
std::map<MTL::Texture*, float> depthClearOps;
|
||||||
std::vector<Metal::StencilClearOp> stencilClearOps;
|
std::map<MTL::Texture*, u8> stencilClearOps;
|
||||||
|
|
||||||
// Active state
|
// Active state
|
||||||
MTL::CommandBuffer* commandBuffer = nullptr;
|
MTL::CommandBuffer* commandBuffer = nullptr;
|
||||||
|
@ -124,32 +109,34 @@ class RendererMTL final : public Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename AttachmentT, typename ClearOpT, typename GetAttachmentT, typename SetClearDataT>
|
template<typename AttachmentT, typename ClearDataT, typename GetAttachmentT, typename SetClearDataT>
|
||||||
inline void clearAttachment(MTL::RenderPassDescriptor* renderPassDescriptor, ClearOpT clearOp, GetAttachmentT getAttachment, SetClearDataT setClearData) {
|
inline void clearAttachment(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* texture, ClearDataT clearData, 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
AttachmentT* attachment = getAttachment();
|
AttachmentT* attachment = getAttachment();
|
||||||
attachment->setTexture(clearOp.texture);
|
attachment->setTexture(texture);
|
||||||
setClearData(attachment, clearOp);
|
setClearData(attachment, clearData);
|
||||||
attachment->setLoadAction(MTL::LoadActionClear);
|
attachment->setLoadAction(MTL::LoadActionClear);
|
||||||
attachment->setStoreAction(MTL::StoreActionStore);
|
attachment->setStoreAction(MTL::StoreActionStore);
|
||||||
|
|
||||||
if (beginRenderPass) {
|
if (beginRenderPass) {
|
||||||
beginRenderPassIfNeeded(renderPassDescriptor, true, clearOp.texture);
|
if (std::is_same<AttachmentT, MTL::RenderPassColorAttachmentDescriptor>::value)
|
||||||
|
beginRenderPassIfNeeded(renderPassDescriptor, true, texture);
|
||||||
|
else
|
||||||
|
beginRenderPassIfNeeded(renderPassDescriptor, true, nullptr, texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename AttachmentT, typename ClearOpT, typename GetAttachmentT, typename SetClearDataT>
|
template<typename AttachmentT, typename ClearDataT, typename GetAttachmentT, typename SetClearDataT>
|
||||||
inline bool clearAttachment(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* texture, std::vector<ClearOpT>& clearOps, GetAttachmentT getAttachment, SetClearDataT setClearData) {
|
inline bool clearAttachment(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* texture, std::map<MTL::Texture*, ClearDataT>& clearOps, GetAttachmentT getAttachment, SetClearDataT setClearData) {
|
||||||
for (int32_t i = clearOps.size() - 1; i >= 0; i--) {
|
auto it = clearOps.find(texture);
|
||||||
if (clearOps[i].texture == texture) {
|
if (it != clearOps.end()) {
|
||||||
clearAttachment<AttachmentT>(renderPassDescriptor, clearOps[i], getAttachment, setClearData);
|
clearAttachment<AttachmentT>(renderPassDescriptor, texture, it->second, getAttachment, setClearData);
|
||||||
clearOps.erase(clearOps.begin() + i);
|
clearOps.erase(it);
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderPassDescriptor) {
|
if (renderPassDescriptor) {
|
||||||
|
@ -163,20 +150,20 @@ class RendererMTL final : public Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clearColor(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* 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) {
|
return clearAttachment<MTL::RenderPassColorAttachmentDescriptor, Color4>(renderPassDescriptor, texture, colorClearOps, [&]() { return renderPassDescriptor->colorAttachments()->object(0); }, [&](auto attachment, auto& color) {
|
||||||
attachment->setClearColor(MTL::ClearColor(clearOp.r, clearOp.g, clearOp.b, clearOp.a));
|
attachment->setClearColor(MTL::ClearColor(color.r, color.g, color.b, color.a));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clearDepth(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* texture) {
|
bool clearDepth(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* texture) {
|
||||||
return clearAttachment<MTL::RenderPassDepthAttachmentDescriptor, Metal::DepthClearOp>(renderPassDescriptor, texture, depthClearOps, [&]() { return renderPassDescriptor->depthAttachment(); }, [&](auto attachment, auto& clearOp) {
|
return clearAttachment<MTL::RenderPassDepthAttachmentDescriptor, float>(renderPassDescriptor, texture, depthClearOps, [&]() { return renderPassDescriptor->depthAttachment(); }, [&](auto attachment, auto& depth) {
|
||||||
attachment->setClearDepth(clearOp.depth);
|
attachment->setClearDepth(depth);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clearStencil(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* texture) {
|
bool clearStencil(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* texture) {
|
||||||
return clearAttachment<MTL::RenderPassStencilAttachmentDescriptor, Metal::StencilClearOp>(renderPassDescriptor, texture, stencilClearOps, [&]() { return renderPassDescriptor->stencilAttachment(); }, [&](auto attachment, auto& clearOp) {
|
return clearAttachment<MTL::RenderPassStencilAttachmentDescriptor, u8>(renderPassDescriptor, texture, stencilClearOps, [&]() { return renderPassDescriptor->stencilAttachment(); }, [&](auto attachment, auto& stencil) {
|
||||||
attachment->setClearStencil(clearOp.stencil);
|
attachment->setClearStencil(stencil);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -266,7 +266,7 @@ void RendererMTL::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 c
|
||||||
const float b = Helpers::getBits<8, 8>(value) / 255.0f;
|
const float b = Helpers::getBits<8, 8>(value) / 255.0f;
|
||||||
const float a = (value & 0xff) / 255.0f;
|
const float a = (value & 0xff) / 255.0f;
|
||||||
|
|
||||||
colorClearOps.push_back({color->get().texture, r, g, b, a});
|
colorClearOps[color->get().texture] = {r, g, b, a};
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -281,11 +281,11 @@ void RendererMTL::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 c
|
||||||
depthVal = (value & 0xffffff) / 16777215.0f;
|
depthVal = (value & 0xffffff) / 16777215.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
depthClearOps.push_back({depth->get().texture, depthVal});
|
depthClearOps[depth->get().texture] = depthVal;
|
||||||
|
|
||||||
if (format == DepthFmt::Depth24Stencil8) {
|
if (format == DepthFmt::Depth24Stencil8) {
|
||||||
const u8 stencilVal = value >> 24;
|
const u8 stencilVal = value >> 24;
|
||||||
stencilClearOps.push_back({depth->get().texture, stencilVal});
|
stencilClearOps[depth->get().texture] = stencilVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue