From 2477326df7e6e1560c657404635c18bed1c067eb Mon Sep 17 00:00:00 2001 From: Isaac Marovitz Date: Sat, 29 Jul 2023 00:46:13 -0400 Subject: [PATCH] SetDepthTest --- src/Ryujinx.Graphics.Metal/Pipeline.cs | 49 ++++++++++--------- .../RenderEncoderState.cs | 44 +++++++++++++++-- 2 files changed, 68 insertions(+), 25 deletions(-) diff --git a/src/Ryujinx.Graphics.Metal/Pipeline.cs b/src/Ryujinx.Graphics.Metal/Pipeline.cs index 04a9bc26f..8ae89131a 100644 --- a/src/Ryujinx.Graphics.Metal/Pipeline.cs +++ b/src/Ryujinx.Graphics.Metal/Pipeline.cs @@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Metal var renderPipelineDescriptor = new MTLRenderPipelineDescriptor(); var error = new NSError(IntPtr.Zero); - _renderEncoderState = new(_device.NewRenderPipelineState(renderPipelineDescriptor, ref error)); + _renderEncoderState = new(_device.NewRenderPipelineState(renderPipelineDescriptor, ref error), _device); if (error != IntPtr.Zero) { Logger.Error?.PrintMsg(LogClass.Gpu, $"Failed to create Render Pipeline State: {StringHelper.String(error.LocalizedDescription)}"); @@ -255,7 +255,14 @@ namespace Ryujinx.Graphics.Metal public void SetDepthTest(DepthTestDescriptor depthTest) { - throw new NotImplementedException(); + var depthStencilState = _renderEncoderState.UpdateDepthState( + depthTest.TestEnable ? MTLCompareFunction.Always : depthTest.Func.Convert(), + depthTest.WriteEnable); + + if (_currentEncoder is MTLRenderCommandEncoder renderCommandEncoder) + { + renderCommandEncoder.SetDepthStencilState(depthStencilState); + } } public void SetFaceCulling(bool enable, Face face) @@ -387,29 +394,27 @@ namespace Ryujinx.Graphics.Metal public void SetStencilTest(StencilTestDescriptor stencilTest) { - var depthStencilDescriptor = new MTLDepthStencilDescriptor + var backFace = new MTLStencilDescriptor { - BackFaceStencil = new MTLStencilDescriptor - { - StencilFailureOperation = stencilTest.BackSFail.Convert(), - DepthFailureOperation = stencilTest.BackDpFail.Convert(), - DepthStencilPassOperation = stencilTest.BackDpPass.Convert(), - StencilCompareFunction = stencilTest.BackFunc.Convert(), - ReadMask = (uint)stencilTest.BackFuncMask, - WriteMask = (uint)stencilTest.BackMask - }, - FrontFaceStencil = new MTLStencilDescriptor - { - StencilFailureOperation = stencilTest.FrontSFail.Convert(), - DepthFailureOperation = stencilTest.FrontDpFail.Convert(), - DepthStencilPassOperation = stencilTest.FrontDpPass.Convert(), - StencilCompareFunction = stencilTest.FrontFunc.Convert(), - ReadMask = (uint)stencilTest.FrontFuncMask, - WriteMask = (uint)stencilTest.FrontMask - } + StencilFailureOperation = stencilTest.BackSFail.Convert(), + DepthFailureOperation = stencilTest.BackDpFail.Convert(), + DepthStencilPassOperation = stencilTest.BackDpPass.Convert(), + StencilCompareFunction = stencilTest.BackFunc.Convert(), + ReadMask = (uint)stencilTest.BackFuncMask, + WriteMask = (uint)stencilTest.BackMask }; - var depthStencilState = _device.NewDepthStencilState(depthStencilDescriptor); + var frontFace = new MTLStencilDescriptor + { + StencilFailureOperation = stencilTest.FrontSFail.Convert(), + DepthFailureOperation = stencilTest.FrontDpFail.Convert(), + DepthStencilPassOperation = stencilTest.FrontDpPass.Convert(), + StencilCompareFunction = stencilTest.FrontFunc.Convert(), + ReadMask = (uint)stencilTest.FrontFuncMask, + WriteMask = (uint)stencilTest.FrontMask + }; + + var depthStencilState = _renderEncoderState.UpdateStencilState(backFace, frontFace); if (_currentEncoder is MTLRenderCommandEncoder renderCommandEncoder) { diff --git a/src/Ryujinx.Graphics.Metal/RenderEncoderState.cs b/src/Ryujinx.Graphics.Metal/RenderEncoderState.cs index 8e0d7b093..a8c719fe9 100644 --- a/src/Ryujinx.Graphics.Metal/RenderEncoderState.cs +++ b/src/Ryujinx.Graphics.Metal/RenderEncoderState.cs @@ -7,14 +7,24 @@ namespace Ryujinx.Graphics.Metal [SupportedOSPlatform("macos")] struct RenderEncoderState { + private MTLDevice _device; + + private MTLDepthStencilState _depthStencilState = null; + + private MTLCompareFunction _depthCompareFunction = MTLCompareFunction.Always; + private bool _depthWriteEnabled = false; + + private MTLStencilDescriptor _backFaceStencil = null; + private MTLStencilDescriptor _frontFaceStencil = null; + public MTLRenderPipelineState RenderPipelineState; public PrimitiveTopology Topology = PrimitiveTopology.Triangles; public MTLCullMode CullMode = MTLCullMode.None; public MTLWinding Winding = MTLWinding.Clockwise; - public MTLDepthStencilState DepthStencilState = null; - public RenderEncoderState(MTLRenderPipelineState renderPipelineState) + public RenderEncoderState(MTLRenderPipelineState renderPipelineState, MTLDevice device) { + _device = device; RenderPipelineState = renderPipelineState; } @@ -23,7 +33,35 @@ namespace Ryujinx.Graphics.Metal renderCommandEncoder.SetRenderPipelineState(RenderPipelineState); renderCommandEncoder.SetCullMode(CullMode); renderCommandEncoder.SetFrontFacingWinding(Winding); - renderCommandEncoder.SetDepthStencilState(DepthStencilState); + renderCommandEncoder.SetDepthStencilState(_depthStencilState); + } + + public MTLDepthStencilState UpdateStencilState(MTLStencilDescriptor backFace, MTLStencilDescriptor frontFace) + { + _backFaceStencil = backFace; + _frontFaceStencil = frontFace; + + return _depthStencilState = _device.NewDepthStencilState(new MTLDepthStencilDescriptor + { + DepthCompareFunction = _depthCompareFunction, + DepthWriteEnabled = _depthWriteEnabled, + BackFaceStencil = _backFaceStencil, + FrontFaceStencil = _frontFaceStencil + }); + } + + public MTLDepthStencilState UpdateDepthState(MTLCompareFunction depthCompareFunction, bool depthWriteEnabled) + { + _depthCompareFunction = depthCompareFunction; + _depthWriteEnabled = depthWriteEnabled; + + return _depthStencilState = _device.NewDepthStencilState(new MTLDepthStencilDescriptor + { + DepthCompareFunction = _depthCompareFunction, + DepthWriteEnabled = _depthWriteEnabled, + BackFaceStencil = _backFaceStencil, + FrontFaceStencil = _frontFaceStencil + }); } } }