16
16
#include " Cafe/HW/Latte/Core/LatteIndices.h"
17
17
#include " Cemu/Logging/CemuDebugLogging.h"
18
18
#include " Common/precompiled.h"
19
+ #include " Metal/MTLRenderPass.hpp"
19
20
#include " gui/guiWrapper.h"
20
21
21
22
#define COMMIT_TRESHOLD 256
@@ -214,10 +215,7 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
214
215
colorAttachment->setLoadAction (clearBackground ? MTL::LoadActionClear : MTL::LoadActionDontCare);
215
216
colorAttachment->setStoreAction (MTL::StoreActionStore);
216
217
217
- MTL::Texture* colorRenderTargets[8 ] = {nullptr };
218
- colorRenderTargets[0 ] = m_drawable->texture ();
219
- // If there was already an encoder with these attachment, we should set the viewport and scissor to default, but that shouldn't happen
220
- auto renderCommandEncoder = GetRenderCommandEncoder (renderPassDescriptor, colorRenderTargets, nullptr , clearBackground, false );
218
+ auto renderCommandEncoder = GetTemporaryRenderCommandEncoder (renderPassDescriptor);
221
219
renderPassDescriptor->release ();
222
220
223
221
// Draw to Metal layer
@@ -226,6 +224,8 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
226
224
renderCommandEncoder->setFragmentSamplerState ((useLinearTexFilter ? m_linearSampler : m_nearestSampler), 0 );
227
225
228
226
renderCommandEncoder->drawPrimitives (MTL::PrimitiveTypeTriangle, NS::UInteger (0 ), NS::UInteger (3 ));
227
+
228
+ EndEncoding ();
229
229
}
230
230
231
231
bool MetalRenderer::BeginFrame (bool mainWindow)
@@ -367,9 +367,9 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl
367
367
stencilAttachment->setLevel (mipIndex);
368
368
}
369
369
370
- MTL::Texture* colorRenderTargets[8 ] = {nullptr };
371
- GetRenderCommandEncoder (renderPassDescriptor, colorRenderTargets, mtlTexture, true );
370
+ GetTemporaryRenderCommandEncoder (renderPassDescriptor);
372
371
renderPassDescriptor->release ();
372
+ EndEncoding ();
373
373
}
374
374
375
375
LatteTexture* MetalRenderer::texture_createTextureEx (Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle, Latte::E_HWTILEMODE tileMode, bool isDepth)
@@ -676,23 +676,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
676
676
return ;
677
677
}
678
678
679
- auto renderPassDescriptor = m_state.m_activeFBO ->GetRenderPassDescriptor ();
680
- MTL::Texture* colorRenderTargets[8 ] = {nullptr };
681
- MTL::Texture* depthRenderTarget = nullptr ;
682
- for (uint32 i = 0 ; i < 8 ; i++)
683
- {
684
- auto colorTexture = static_cast <LatteTextureViewMtl*>(m_state.m_activeFBO ->colorBuffer [i].texture );
685
- if (colorTexture)
686
- {
687
- colorRenderTargets[i] = colorTexture->GetRGBAView ();
688
- }
689
- }
690
- auto depthTexture = static_cast <LatteTextureViewMtl*>(m_state.m_activeFBO ->depthBuffer .texture );
691
- if (depthTexture)
692
- {
693
- depthRenderTarget = depthTexture->GetRGBAView ();
694
- }
695
- auto renderCommandEncoder = GetRenderCommandEncoder (renderPassDescriptor, colorRenderTargets, depthRenderTarget);
679
+ auto renderCommandEncoder = GetRenderCommandEncoder ();
696
680
697
681
// Shaders
698
682
LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader ();
@@ -705,7 +689,8 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
705
689
const auto fetchShader = LatteSHRC_GetActiveFetchShader ();
706
690
707
691
// Render pipeline state
708
- MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState (fetchShader, vertexShader, pixelShader, m_state.m_lastUsedFBO , LatteGPUState.contextNew );
692
+ // TODO: use `m_lastUsedFBO` instead of `m_activeFBO`
693
+ MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState (fetchShader, vertexShader, pixelShader, m_state.m_activeFBO , LatteGPUState.contextNew );
709
694
renderCommandEncoder->setRenderPipelineState (renderPipelineState);
710
695
711
696
// Depth stencil state
@@ -886,8 +871,21 @@ void MetalRenderer::WaitForCommandBufferCompletion(MTL::CommandBuffer* commandBu
886
871
commandBuffer->waitUntilCompleted ();
887
872
}
888
873
874
+ MTL::RenderCommandEncoder* MetalRenderer::GetTemporaryRenderCommandEncoder (MTL::RenderPassDescriptor* renderPassDescriptor)
875
+ {
876
+ EndEncoding ();
877
+
878
+ auto commandBuffer = GetCommandBuffer ();
879
+
880
+ auto renderCommandEncoder = commandBuffer->renderCommandEncoder (renderPassDescriptor);
881
+ m_commandEncoder = renderCommandEncoder;
882
+ m_encoderType = MetalEncoderType::Render;
883
+
884
+ return renderCommandEncoder;
885
+ }
886
+
889
887
// Some render passes clear the attachments, forceRecreate is supposed to be used in those cases
890
- MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder (MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorRenderTargets[ 8 ], MTL::Texture* depthRenderTarget, bool forceRecreate, bool rebindStateIfNewEncoder)
888
+ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder (bool forceRecreate, bool rebindStateIfNewEncoder)
891
889
{
892
890
// Check if we need to begin a new render pass
893
891
if (m_commandEncoder)
@@ -896,19 +894,22 @@ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(MTL::RenderPas
896
894
{
897
895
if (m_encoderType == MetalEncoderType::Render)
898
896
{
899
- bool needsNewRenderPass = false ;
900
- for (uint8 i = 0 ; i < 8 ; i++ )
897
+ bool needsNewRenderPass = (m_state. m_lastUsedFBO == nullptr ) ;
898
+ if (!needsNewRenderPass )
901
899
{
902
- if (colorRenderTargets[i] && (colorRenderTargets[i] != m_state. m_colorRenderTargets [i]) )
900
+ for (uint8 i = 0 ; i < 8 ; i++ )
903
901
{
904
- needsNewRenderPass = true ;
905
- break ;
902
+ if (m_state.m_activeFBO ->colorBuffer [i].texture && m_state.m_activeFBO ->colorBuffer [i].texture != m_state.m_lastUsedFBO ->colorBuffer [i].texture )
903
+ {
904
+ needsNewRenderPass = true ;
905
+ break ;
906
+ }
906
907
}
907
908
}
908
909
909
910
if (!needsNewRenderPass)
910
911
{
911
- if (depthRenderTarget && (depthRenderTarget != m_state.m_depthRenderTarget ) )
912
+ if (m_state. m_activeFBO -> depthBuffer . texture && m_state. m_activeFBO -> depthBuffer . texture != m_state.m_lastUsedFBO -> depthBuffer . texture )
912
913
{
913
914
needsNewRenderPass = true ;
914
915
}
@@ -928,13 +929,8 @@ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(MTL::RenderPas
928
929
929
930
// Update state
930
931
m_state.m_lastUsedFBO = m_state.m_activeFBO ;
931
- for (uint8 i = 0 ; i < 8 ; i++)
932
- {
933
- m_state.m_colorRenderTargets [i] = colorRenderTargets[i];
934
- }
935
- m_state.m_depthRenderTarget = depthRenderTarget;
936
932
937
- auto renderCommandEncoder = commandBuffer->renderCommandEncoder (renderPassDescriptor );
933
+ auto renderCommandEncoder = commandBuffer->renderCommandEncoder (m_state. m_activeFBO -> GetRenderPassDescriptor () );
938
934
m_commandEncoder = renderCommandEncoder;
939
935
m_encoderType = MetalEncoderType::Render;
940
936
@@ -991,10 +987,11 @@ MTL::BlitCommandEncoder* MetalRenderer::GetBlitCommandEncoder()
991
987
992
988
void MetalRenderer::EndEncoding ()
993
989
{
994
- if (m_encoderType != MetalEncoderType::None )
990
+ if (m_commandEncoder )
995
991
{
996
992
m_commandEncoder->endEncoding ();
997
993
m_commandEncoder->release ();
994
+ m_commandEncoder = nullptr ;
998
995
m_encoderType = MetalEncoderType::None;
999
996
1000
997
// Commit the command buffer if enough draw calls have been recorded
@@ -1427,6 +1424,7 @@ void MetalRenderer::ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 s
1427
1424
1428
1425
MTL::Texture* colorRenderTargets[8 ] = {nullptr };
1429
1426
colorRenderTargets[0 ] = mtlTexture;
1430
- GetRenderCommandEncoder (renderPassDescriptor, colorRenderTargets, nullptr , true );
1427
+ GetTemporaryRenderCommandEncoder (renderPassDescriptor);
1431
1428
renderPassDescriptor->release ();
1429
+ EndEncoding ();
1432
1430
}
0 commit comments