From 0c216e40e067bbd2c934e2a6aa68fbf58fa7fe02 Mon Sep 17 00:00:00 2001 From: Samuliak Date: Sat, 25 Jan 2025 20:23:22 +0100 Subject: [PATCH] speed up render pass change check --- .../HW/Latte/Renderer/Metal/MetalRenderer.cpp | 30 ++++++++++++------- .../HW/Latte/Renderer/Metal/MetalRenderer.h | 1 + 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index 7bae23e9..eccab5ab 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -698,6 +698,7 @@ void MetalRenderer::rendertarget_deleteCachedFBO(LatteCachedFBO* cfbo) void MetalRenderer::rendertarget_bindFramebufferObject(LatteCachedFBO* cfbo) { m_state.m_activeFBO = {(CachedFBOMtl*)cfbo, MetalAttachmentsInfo((CachedFBOMtl*)cfbo)}; + m_state.m_fboChanged = true; } void* MetalRenderer::texture_acquireTextureUploadBuffer(uint32 size) @@ -1732,6 +1733,9 @@ MTL::RenderCommandEncoder* MetalRenderer::GetTemporaryRenderCommandEncoder(MTL:: // Some render passes clear the attachments, forceRecreate is supposed to be used in those cases MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(bool forceRecreate) { + bool fboChanged = m_state.m_fboChanged; + m_state.m_fboChanged = false; + // Check if we need to begin a new render pass if (m_commandEncoder) { @@ -1739,24 +1743,28 @@ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(bool forceRecr { if (m_encoderType == MetalEncoderType::Render) { - bool needsNewRenderPass = (m_state.m_lastUsedFBO.m_fbo == nullptr); - if (!needsNewRenderPass) + bool needsNewRenderPass = false; + if (fboChanged) { - for (uint8 i = 0; i < 8; i++) + needsNewRenderPass = (m_state.m_lastUsedFBO.m_fbo == nullptr); + if (!needsNewRenderPass) { - if (m_state.m_activeFBO.m_fbo->colorBuffer[i].texture && m_state.m_activeFBO.m_fbo->colorBuffer[i].texture != m_state.m_lastUsedFBO.m_fbo->colorBuffer[i].texture) + for (uint8 i = 0; i < 8; i++) { - needsNewRenderPass = true; - break; + if (m_state.m_activeFBO.m_fbo->colorBuffer[i].texture && m_state.m_activeFBO.m_fbo->colorBuffer[i].texture != m_state.m_lastUsedFBO.m_fbo->colorBuffer[i].texture) + { + needsNewRenderPass = true; + break; + } } } - } - if (!needsNewRenderPass) - { - if (m_state.m_activeFBO.m_fbo->depthBuffer.texture && (m_state.m_activeFBO.m_fbo->depthBuffer.texture != m_state.m_lastUsedFBO.m_fbo->depthBuffer.texture || ( m_state.m_activeFBO.m_fbo->depthBuffer.hasStencil && !m_state.m_lastUsedFBO.m_fbo->depthBuffer.hasStencil))) + if (!needsNewRenderPass) { - needsNewRenderPass = true; + if (m_state.m_activeFBO.m_fbo->depthBuffer.texture && (m_state.m_activeFBO.m_fbo->depthBuffer.texture != m_state.m_lastUsedFBO.m_fbo->depthBuffer.texture || ( m_state.m_activeFBO.m_fbo->depthBuffer.hasStencil && !m_state.m_lastUsedFBO.m_fbo->depthBuffer.hasStencil))) + { + needsNewRenderPass = true; + } } } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h index 9a2b168c..6dc780d8 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h @@ -111,6 +111,7 @@ struct MetalState MetalActiveFBOState m_activeFBO; // If the FBO changes, but it's the same FBO as the last one with some omitted attachments, this FBO doesn't change MetalActiveFBOState m_lastUsedFBO; + bool m_fboChanged = false; size_t m_vertexBufferOffsets[MAX_MTL_VERTEX_BUFFERS]; class LatteTextureViewMtl* m_textures[LATTE_NUM_MAX_TEX_UNITS * 3] = {nullptr};