16
16
#include " Cemu/Logging/CemuDebugLogging.h"
17
17
#include " HW/Latte/Core/Latte.h"
18
18
#include " HW/Latte/ISA/LatteReg.h"
19
+ #include " Metal/MTLRenderCommandEncoder.hpp"
19
20
#include " Metal/MTLResource.hpp"
20
21
#include " Metal/MTLTypes.hpp"
21
22
#include " gui/guiWrapper.h"
@@ -600,7 +601,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
600
601
const auto fetchShader = LatteSHRC_GetActiveFetchShader ();
601
602
602
603
// Render pipeline state
603
- MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState (fetchShader, vertexShader, pixelShader, m_state.activeFBO , LatteGPUState.contextNew );
604
+ MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState (fetchShader, vertexShader, pixelShader, m_state.lastUsedFBO , LatteGPUState.contextNew );
604
605
renderCommandEncoder->setRenderPipelineState (renderPipelineState);
605
606
606
607
// Depth stencil state
@@ -620,9 +621,54 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
620
621
renderCommandEncoder->setStencilReferenceValue (stencilRefFront);
621
622
}
622
623
623
- // Primitive type
624
- const LattePrimitiveMode primitiveMode = static_cast <LattePrimitiveMode>(LatteGPUState.contextRegister [mmVGT_PRIMITIVE_TYPE]);
625
- auto mtlPrimitiveType = GetMtlPrimitiveType (primitiveMode);
624
+ // Primitive type
625
+ const LattePrimitiveMode primitiveMode = static_cast <LattePrimitiveMode>(LatteGPUState.contextRegister [mmVGT_PRIMITIVE_TYPE]);
626
+ auto mtlPrimitiveType = GetMtlPrimitiveType (primitiveMode);
627
+ bool isPrimitiveRect = (primitiveMode == Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::RECTS);
628
+
629
+ // Blend color
630
+ float * blendColorConstant = (float *)LatteGPUState.contextRegister + Latte::REGADDR::CB_BLEND_RED;
631
+ renderCommandEncoder->setBlendColor (blendColorConstant[0 ], blendColorConstant[1 ], blendColorConstant[2 ], blendColorConstant[3 ]);
632
+
633
+ // polygon control
634
+ const auto & polygonControlReg = LatteGPUState.contextNew .PA_SU_SC_MODE_CNTL ;
635
+ const auto frontFace = polygonControlReg.get_FRONT_FACE ();
636
+ uint32 cullFront = polygonControlReg.get_CULL_FRONT ();
637
+ uint32 cullBack = polygonControlReg.get_CULL_BACK ();
638
+ uint32 polyOffsetFrontEnable = polygonControlReg.get_OFFSET_FRONT_ENABLED ();
639
+
640
+ // TODO
641
+ // cemu_assert_debug(LatteGPUState.contextNew.PA_CL_CLIP_CNTL.get_ZCLIP_NEAR_DISABLE() == LatteGPUState.contextNew.PA_CL_CLIP_CNTL.get_ZCLIP_FAR_DISABLE()); // near or far clipping can be disabled individually
642
+ // bool zClipEnable = LatteGPUState.contextNew.PA_CL_CLIP_CNTL.get_ZCLIP_FAR_DISABLE() == false;
643
+
644
+ if (polyOffsetFrontEnable)
645
+ {
646
+ // TODO: set depth bias
647
+ }
648
+
649
+ // todo - how does culling behave with rects?
650
+ // right now we just assume that their winding is always CW
651
+ if (isPrimitiveRect)
652
+ {
653
+ if (frontFace == Latte::LATTE_PA_SU_SC_MODE_CNTL::E_FRONTFACE::CW)
654
+ cullFront = cullBack;
655
+ else
656
+ cullBack = cullFront;
657
+ }
658
+
659
+ if (cullFront && cullBack)
660
+ return ; // We can just skip the draw (TODO: can we?)
661
+ else if (cullFront)
662
+ renderCommandEncoder->setCullMode (MTL::CullModeFront);
663
+ else if (cullBack)
664
+ renderCommandEncoder->setCullMode (MTL::CullModeBack);
665
+ else
666
+ renderCommandEncoder->setCullMode (MTL::CullModeNone);
667
+
668
+ if (frontFace == Latte::LATTE_PA_SU_SC_MODE_CNTL::E_FRONTFACE::CCW)
669
+ renderCommandEncoder->setFrontFacingWinding (MTL::WindingCounterClockwise);
670
+ else
671
+ renderCommandEncoder->setFrontFacingWinding (MTL::WindingClockwise);
626
672
627
673
// Resources
628
674
@@ -708,7 +754,7 @@ void MetalRenderer::EnsureCommandBuffer()
708
754
if (!m_commandBuffer)
709
755
{
710
756
// Debug
711
- m_commandQueue->insertDebugCaptureBoundary ();
757
+ // m_commandQueue->insertDebugCaptureBoundary();
712
758
713
759
m_commandBuffer = m_commandQueue->commandBuffer ();
714
760
}
@@ -755,6 +801,7 @@ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(MTL::RenderPas
755
801
}
756
802
757
803
// Update state
804
+ m_state.lastUsedFBO = m_state.activeFBO ;
758
805
for (uint8 i = 0 ; i < 8 ; i++)
759
806
{
760
807
m_state.colorRenderTargets [i] = colorRenderTargets[i];
@@ -836,7 +883,7 @@ void MetalRenderer::CommitCommandBuffer()
836
883
LatteTextureReadback_UpdateFinishedTransfers (false );
837
884
838
885
// Debug
839
- m_commandQueue->insertDebugCaptureBoundary ();
886
+ // m_commandQueue->insertDebugCaptureBoundary();
840
887
}
841
888
}
842
889
0 commit comments