mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-16 18:59:48 +12:00
only begin a new render pass when necessary
This commit is contained in:
parent
9ec116da18
commit
ea56f45fc2
2 changed files with 59 additions and 40 deletions
|
@ -52,6 +52,9 @@ class RendererMTL final : public Renderer {
|
||||||
|
|
||||||
// Active state
|
// Active state
|
||||||
MTL::CommandBuffer* commandBuffer = nullptr;
|
MTL::CommandBuffer* commandBuffer = nullptr;
|
||||||
|
MTL::RenderCommandEncoder* renderCommandEncoder = nullptr;
|
||||||
|
MTL::Texture* lastColorTexture = nullptr;
|
||||||
|
MTL::Texture* lastDepthTexture = nullptr;
|
||||||
|
|
||||||
void createCommandBufferIfNeeded() {
|
void createCommandBufferIfNeeded() {
|
||||||
if (!commandBuffer) {
|
if (!commandBuffer) {
|
||||||
|
@ -59,6 +62,37 @@ class RendererMTL final : public Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void endRenderPass() {
|
||||||
|
if (renderCommandEncoder) {
|
||||||
|
renderCommandEncoder->endEncoding();
|
||||||
|
renderCommandEncoder = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void beginRenderPassIfNeeded(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorTexture, MTL::Texture* depthTexture) {
|
||||||
|
createCommandBufferIfNeeded();
|
||||||
|
|
||||||
|
if (!renderCommandEncoder || colorTexture != lastColorTexture || depthTexture != lastDepthTexture) {
|
||||||
|
endRenderPass();
|
||||||
|
|
||||||
|
renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor);
|
||||||
|
|
||||||
|
lastColorTexture = colorTexture;
|
||||||
|
lastDepthTexture = depthTexture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void commitCommandBuffer() {
|
||||||
|
if (renderCommandEncoder) {
|
||||||
|
renderCommandEncoder->endEncoding();
|
||||||
|
renderCommandEncoder = nullptr;
|
||||||
|
}
|
||||||
|
if (commandBuffer) {
|
||||||
|
commandBuffer->commit();
|
||||||
|
commandBuffer = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
Metal::DepthStencilRenderTarget& getDepthRenderTarget();
|
Metal::DepthStencilRenderTarget& getDepthRenderTarget();
|
||||||
MTL::Texture* getTexture(Metal::Texture& tex);
|
MTL::Texture* getTexture(Metal::Texture& tex);
|
||||||
|
|
|
@ -33,8 +33,6 @@ void RendererMTL::reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererMTL::display() {
|
void RendererMTL::display() {
|
||||||
createCommandBufferIfNeeded();
|
|
||||||
|
|
||||||
CA::MetalDrawable* drawable = metalLayer->nextDrawable();
|
CA::MetalDrawable* drawable = metalLayer->nextDrawable();
|
||||||
|
|
||||||
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||||
|
@ -44,7 +42,7 @@ void RendererMTL::display() {
|
||||||
colorAttachment->setClearColor(MTL::ClearColor{0.0f, 0.0f, 0.0f, 1.0f});
|
colorAttachment->setClearColor(MTL::ClearColor{0.0f, 0.0f, 0.0f, 1.0f});
|
||||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||||
|
|
||||||
MTL::RenderCommandEncoder* renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor);
|
beginRenderPassIfNeeded(renderPassDescriptor, drawable->texture(), nullptr);
|
||||||
renderCommandEncoder->setRenderPipelineState(displayPipeline);
|
renderCommandEncoder->setRenderPipelineState(displayPipeline);
|
||||||
renderCommandEncoder->setFragmentSamplerState(basicSampler, 0);
|
renderCommandEncoder->setFragmentSamplerState(basicSampler, 0);
|
||||||
|
|
||||||
|
@ -76,11 +74,10 @@ void RendererMTL::display() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCommandEncoder->endEncoding();
|
endRenderPass();
|
||||||
|
|
||||||
commandBuffer->presentDrawable(drawable);
|
commandBuffer->presentDrawable(drawable);
|
||||||
commandBuffer->commit();
|
commitCommandBuffer();
|
||||||
commandBuffer = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererMTL::initGraphicsContext(SDL_Window* window) {
|
void RendererMTL::initGraphicsContext(SDL_Window* window) {
|
||||||
|
@ -197,8 +194,6 @@ void RendererMTL::initGraphicsContext(SDL_Window* window) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererMTL::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) {
|
void RendererMTL::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) {
|
||||||
createCommandBufferIfNeeded();
|
|
||||||
|
|
||||||
const auto color = colorRenderTargetCache.findFromAddress(startAddress);
|
const auto color = colorRenderTargetCache.findFromAddress(startAddress);
|
||||||
if (color) {
|
if (color) {
|
||||||
const float r = Helpers::getBits<24, 8>(value) / 255.0f;
|
const float r = Helpers::getBits<24, 8>(value) / 255.0f;
|
||||||
|
@ -206,15 +201,14 @@ 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;
|
||||||
|
|
||||||
MTL::RenderPassDescriptor* passDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = passDescriptor->colorAttachments()->object(0);
|
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
||||||
colorAttachment->setTexture(color->get().texture);
|
colorAttachment->setTexture(color->get().texture);
|
||||||
colorAttachment->setClearColor(MTL::ClearColor(r, g, b, a));
|
colorAttachment->setClearColor(MTL::ClearColor(r, g, b, a));
|
||||||
colorAttachment->setLoadAction(MTL::LoadActionClear);
|
colorAttachment->setLoadAction(MTL::LoadActionClear);
|
||||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||||
|
|
||||||
MTL::RenderCommandEncoder* renderEncoder = commandBuffer->renderCommandEncoder(passDescriptor);
|
beginRenderPassIfNeeded(renderPassDescriptor, color->get().texture, nullptr);
|
||||||
renderEncoder->endEncoding();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -236,26 +230,23 @@ void RendererMTL::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 c
|
||||||
//OpenGL::setClearStencil(stencil);
|
//OpenGL::setClearStencil(stencil);
|
||||||
//OpenGL::clearDepthAndStencil();
|
//OpenGL::clearDepthAndStencil();
|
||||||
} else {
|
} else {
|
||||||
MTL::RenderPassDescriptor* passDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||||
MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = passDescriptor->depthAttachment();
|
MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = renderPassDescriptor->depthAttachment();
|
||||||
depthAttachment->setTexture(depth->get().texture);
|
depthAttachment->setTexture(depth->get().texture);
|
||||||
depthAttachment->setClearDepth(depthVal);
|
depthAttachment->setClearDepth(depthVal);
|
||||||
depthAttachment->setLoadAction(MTL::LoadActionClear);
|
depthAttachment->setLoadAction(MTL::LoadActionClear);
|
||||||
depthAttachment->setStoreAction(MTL::StoreActionStore);
|
depthAttachment->setStoreAction(MTL::StoreActionStore);
|
||||||
|
|
||||||
MTL::RenderCommandEncoder* renderEncoder = commandBuffer->renderCommandEncoder(passDescriptor);
|
beginRenderPassIfNeeded(renderPassDescriptor, nullptr, depth->get().texture);
|
||||||
renderEncoder->endEncoding();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Helpers::warn("[RendererGL::ClearBuffer] No buffer found!\n");
|
Helpers::warn("[RendererMTL::ClearBuffer] No buffer found!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererMTL::displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags) {
|
void RendererMTL::displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags) {
|
||||||
createCommandBufferIfNeeded();
|
|
||||||
|
|
||||||
const u32 inputWidth = inputSize & 0xffff;
|
const u32 inputWidth = inputSize & 0xffff;
|
||||||
const u32 inputHeight = inputSize >> 16;
|
const u32 inputHeight = inputSize >> 16;
|
||||||
const auto inputFormat = ToColorFormat(Helpers::getBits<8, 3>(flags));
|
const auto inputFormat = ToColorFormat(Helpers::getBits<8, 3>(flags));
|
||||||
|
@ -301,14 +292,12 @@ void RendererMTL::displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize,
|
||||||
Metal::PipelineHash hash{destFramebuffer->format, DepthFmt::Unknown1};
|
Metal::PipelineHash hash{destFramebuffer->format, DepthFmt::Unknown1};
|
||||||
auto blitPipeline = blitPipelineCache.get(hash);
|
auto blitPipeline = blitPipelineCache.get(hash);
|
||||||
|
|
||||||
MTL::RenderCommandEncoder* renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor);
|
beginRenderPassIfNeeded(renderPassDescriptor, destFramebuffer->texture, nullptr);
|
||||||
renderCommandEncoder->setRenderPipelineState(blitPipeline);
|
renderCommandEncoder->setRenderPipelineState(blitPipeline);
|
||||||
renderCommandEncoder->setFragmentTexture(srcFramebuffer->texture, 0);
|
renderCommandEncoder->setFragmentTexture(srcFramebuffer->texture, 0);
|
||||||
renderCommandEncoder->setFragmentSamplerState(basicSampler, 0);
|
renderCommandEncoder->setFragmentSamplerState(basicSampler, 0);
|
||||||
|
|
||||||
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangleStrip, NS::UInteger(0), NS::UInteger(4));
|
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangleStrip, NS::UInteger(0), NS::UInteger(4));
|
||||||
|
|
||||||
renderCommandEncoder->endEncoding();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererMTL::textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32 inputSize, u32 outputSize, u32 flags) {
|
void RendererMTL::textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32 inputSize, u32 outputSize, u32 flags) {
|
||||||
|
@ -317,8 +306,6 @@ void RendererMTL::textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererMTL::drawVertices(PICA::PrimType primType, std::span<const PICA::Vertex> vertices) {
|
void RendererMTL::drawVertices(PICA::PrimType primType, std::span<const PICA::Vertex> vertices) {
|
||||||
createCommandBufferIfNeeded();
|
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
auto colorRenderTarget = getColorRenderTarget(colourBufferLoc, colourBufferFormat, fbSize[0], fbSize[1]);
|
auto colorRenderTarget = getColorRenderTarget(colourBufferLoc, colourBufferFormat, fbSize[0], fbSize[1]);
|
||||||
|
|
||||||
|
@ -351,19 +338,6 @@ void RendererMTL::drawVertices(PICA::PrimType primType, std::span<const PICA::Ve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: don't begin a new render pass every time
|
|
||||||
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
|
||||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
|
||||||
colorAttachment->setTexture(colorRenderTarget->texture);
|
|
||||||
colorAttachment->setLoadAction(MTL::LoadActionLoad);
|
|
||||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
|
||||||
if (depthStencilRenderTarget) {
|
|
||||||
MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = renderPassDescriptor->depthAttachment();
|
|
||||||
depthAttachment->setTexture(depthStencilRenderTarget->texture);
|
|
||||||
depthAttachment->setLoadAction(MTL::LoadActionLoad);
|
|
||||||
depthAttachment->setStoreAction(MTL::StoreActionStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------- Pipeline --------
|
// -------- Pipeline --------
|
||||||
Metal::PipelineHash pipelineHash{colorRenderTarget->format, DepthFmt::Unknown1};
|
Metal::PipelineHash pipelineHash{colorRenderTarget->format, DepthFmt::Unknown1};
|
||||||
if (depthStencilRenderTarget) {
|
if (depthStencilRenderTarget) {
|
||||||
|
@ -388,7 +362,20 @@ void RendererMTL::drawVertices(PICA::PrimType primType, std::span<const PICA::Ve
|
||||||
// Depth stencil state
|
// Depth stencil state
|
||||||
MTL::DepthStencilState* depthStencilState = depthStencilCache.get(depthStencilHash);
|
MTL::DepthStencilState* depthStencilState = depthStencilCache.get(depthStencilHash);
|
||||||
|
|
||||||
MTL::RenderCommandEncoder* renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor);
|
// -------- Render --------
|
||||||
|
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||||
|
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
||||||
|
colorAttachment->setTexture(colorRenderTarget->texture);
|
||||||
|
colorAttachment->setLoadAction(MTL::LoadActionLoad);
|
||||||
|
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||||
|
if (depthStencilRenderTarget) {
|
||||||
|
MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = renderPassDescriptor->depthAttachment();
|
||||||
|
depthAttachment->setTexture(depthStencilRenderTarget->texture);
|
||||||
|
depthAttachment->setLoadAction(MTL::LoadActionLoad);
|
||||||
|
depthAttachment->setStoreAction(MTL::StoreActionStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
beginRenderPassIfNeeded(renderPassDescriptor, colorRenderTarget->texture, (depthStencilRenderTarget ? depthStencilRenderTarget->texture : nullptr));
|
||||||
renderCommandEncoder->setRenderPipelineState(pipeline);
|
renderCommandEncoder->setRenderPipelineState(pipeline);
|
||||||
renderCommandEncoder->setDepthStencilState(depthStencilState);
|
renderCommandEncoder->setDepthStencilState(depthStencilState);
|
||||||
// If size is < 4KB, use inline vertex data, otherwise use a buffer
|
// If size is < 4KB, use inline vertex data, otherwise use a buffer
|
||||||
|
@ -408,8 +395,6 @@ void RendererMTL::drawVertices(PICA::PrimType primType, std::span<const PICA::Ve
|
||||||
|
|
||||||
// TODO: respect primitive type
|
// TODO: respect primitive type
|
||||||
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(vertices.size()));
|
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(vertices.size()));
|
||||||
|
|
||||||
renderCommandEncoder->endEncoding();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererMTL::screenshot(const std::string& name) {
|
void RendererMTL::screenshot(const std::string& name) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue