mirror of
https://github.com/GreemDev/Ryujinx
synced 2024-12-13 03:29:56 +01:00
Fix Cull FrontAndBack
This commit is contained in:
parent
a60643620d
commit
b7ddb693bc
2 changed files with 28 additions and 6 deletions
|
@ -90,6 +90,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
public PrimitiveTopology Topology = PrimitiveTopology.Triangles;
|
public PrimitiveTopology Topology = PrimitiveTopology.Triangles;
|
||||||
public MTLCullMode CullMode = MTLCullMode.None;
|
public MTLCullMode CullMode = MTLCullMode.None;
|
||||||
public MTLWinding Winding = MTLWinding.CounterClockwise;
|
public MTLWinding Winding = MTLWinding.CounterClockwise;
|
||||||
|
public bool CullBoth = false;
|
||||||
|
|
||||||
public MTLViewport[] Viewports = [];
|
public MTLViewport[] Viewports = [];
|
||||||
public MTLScissorRect[] Scissors = [];
|
public MTLScissorRect[] Scissors = [];
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
struct EncoderStateManager : IDisposable
|
struct EncoderStateManager : IDisposable
|
||||||
{
|
{
|
||||||
|
private readonly MTLDevice _device;
|
||||||
private readonly Pipeline _pipeline;
|
private readonly Pipeline _pipeline;
|
||||||
private readonly BufferManager _bufferManager;
|
private readonly BufferManager _bufferManager;
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public unsafe EncoderStateManager(MTLDevice device, BufferManager bufferManager, Pipeline pipeline)
|
public unsafe EncoderStateManager(MTLDevice device, BufferManager bufferManager, Pipeline pipeline)
|
||||||
{
|
{
|
||||||
|
_device = device;
|
||||||
_pipeline = pipeline;
|
_pipeline = pipeline;
|
||||||
_bufferManager = bufferManager;
|
_bufferManager = bufferManager;
|
||||||
|
|
||||||
|
@ -533,7 +535,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
descriptor.FrontFaceStencil = _currentState.FrontFaceStencil;
|
descriptor.FrontFaceStencil = _currentState.FrontFaceStencil;
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentState.DepthStencilState = _depthStencilCache.GetOrCreate(descriptor);
|
_currentState.DepthStencilState = _device.NewDepthStencilState(descriptor);
|
||||||
|
|
||||||
UpdateStencilRefValue(stencilTest.FrontFuncRef, stencilTest.BackFuncRef);
|
UpdateStencilRefValue(stencilTest.FrontFuncRef, stencilTest.BackFuncRef);
|
||||||
|
|
||||||
|
@ -547,7 +549,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
public void UpdateDepthState(DepthTestDescriptor depthTest)
|
public void UpdateDepthState(DepthTestDescriptor depthTest)
|
||||||
{
|
{
|
||||||
_currentState.DepthCompareFunction = depthTest.TestEnable ? depthTest.Func.Convert() : MTLCompareFunction.Always;
|
_currentState.DepthCompareFunction = depthTest.TestEnable ? depthTest.Func.Convert() : MTLCompareFunction.Always;
|
||||||
_currentState.DepthWriteEnabled = depthTest.WriteEnable;
|
_currentState.DepthWriteEnabled = depthTest.TestEnable && depthTest.WriteEnable;
|
||||||
|
|
||||||
var descriptor = new MTLDepthStencilDescriptor
|
var descriptor = new MTLDepthStencilDescriptor
|
||||||
{
|
{
|
||||||
|
@ -561,7 +563,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
descriptor.FrontFaceStencil = _currentState.FrontFaceStencil;
|
descriptor.FrontFaceStencil = _currentState.FrontFaceStencil;
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentState.DepthStencilState = _depthStencilCache.GetOrCreate(descriptor);
|
_currentState.DepthStencilState = _device.NewDepthStencilState(descriptor);
|
||||||
|
|
||||||
// Mark dirty
|
// Mark dirty
|
||||||
_currentState.Dirty |= DirtyFlags.DepthStencil;
|
_currentState.Dirty |= DirtyFlags.DepthStencil;
|
||||||
|
@ -741,18 +743,27 @@ namespace Ryujinx.Graphics.Metal
|
||||||
// Inlineable
|
// Inlineable
|
||||||
public void UpdateCullMode(bool enable, Face face)
|
public void UpdateCullMode(bool enable, Face face)
|
||||||
{
|
{
|
||||||
|
var dirtyScissor = (face == Face.FrontAndBack) != _currentState.CullBoth;
|
||||||
|
|
||||||
_currentState.CullMode = enable ? face.Convert() : MTLCullMode.None;
|
_currentState.CullMode = enable ? face.Convert() : MTLCullMode.None;
|
||||||
|
_currentState.CullBoth = face == Face.FrontAndBack;
|
||||||
|
|
||||||
// Inline update
|
// Inline update
|
||||||
if (_pipeline.CurrentEncoderType == EncoderType.Render && _pipeline.CurrentEncoder != null)
|
if (_pipeline.CurrentEncoderType == EncoderType.Render && _pipeline.CurrentEncoder != null)
|
||||||
{
|
{
|
||||||
var renderCommandEncoder = new MTLRenderCommandEncoder(_pipeline.CurrentEncoder.Value);
|
var renderCommandEncoder = new MTLRenderCommandEncoder(_pipeline.CurrentEncoder.Value);
|
||||||
SetCullMode(renderCommandEncoder);
|
SetCullMode(renderCommandEncoder);
|
||||||
|
SetScissors(renderCommandEncoder);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark dirty
|
// Mark dirty
|
||||||
_currentState.Dirty |= DirtyFlags.CullMode;
|
_currentState.Dirty |= DirtyFlags.CullMode;
|
||||||
|
|
||||||
|
if (dirtyScissor)
|
||||||
|
{
|
||||||
|
_currentState.Dirty |= DirtyFlags.Scissors;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inlineable
|
// Inlineable
|
||||||
|
@ -862,11 +873,21 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
private unsafe void SetScissors(MTLRenderCommandEncoder renderCommandEncoder)
|
private unsafe void SetScissors(MTLRenderCommandEncoder renderCommandEncoder)
|
||||||
{
|
{
|
||||||
if (_currentState.Scissors.Length > 0)
|
var isTriangles = (_currentState.Topology == PrimitiveTopology.Triangles) ||
|
||||||
|
(_currentState.Topology == PrimitiveTopology.TriangleStrip);
|
||||||
|
|
||||||
|
if (_currentState.CullBoth && isTriangles)
|
||||||
{
|
{
|
||||||
fixed (MTLScissorRect* pMtlScissors = _currentState.Scissors)
|
renderCommandEncoder.SetScissorRect(new MTLScissorRect { x = 0, y = 0, width = 0, height = 0});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_currentState.Scissors.Length > 0)
|
||||||
{
|
{
|
||||||
renderCommandEncoder.SetScissorRects((IntPtr)pMtlScissors, (ulong)_currentState.Scissors.Length);
|
fixed (MTLScissorRect* pMtlScissors = _currentState.Scissors)
|
||||||
|
{
|
||||||
|
renderCommandEncoder.SetScissorRects((IntPtr)pMtlScissors, (ulong)_currentState.Scissors.Length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue