implement depth stencil cache

This commit is contained in:
Samuliak 2024-05-23 15:48:20 +02:00 committed by Isaac Marovitz
parent 20beb2e250
commit 0d15f0fc90
2 changed files with 77 additions and 2 deletions

View file

@ -0,0 +1,73 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using SharpMetal.Foundation;
using SharpMetal.Metal;
using System;
using System.Collections.Generic;
using System.Runtime.Versioning;
namespace Ryujinx.Graphics.Metal
{
[SupportedOSPlatform("macos")]
public struct DepthStencilHash
{
public struct StencilHash
{
public MTLStencilOperation StencilFailureOperation;
public MTLStencilOperation DepthFailureOperation;
public MTLStencilOperation DepthStencilPassOperation;
public MTLCompareFunction StencilCompareFunction;
public uint ReadMask;
public uint WriteMask;
}
public StencilHash FrontFace;
public StencilHash BackFace;
public MTLCompareFunction DepthCompareFunction;
public bool DepthWriteEnabled;
}
[SupportedOSPlatform("macos")]
public class DepthStencilCache : StateCache<MTLDepthStencilState, MTLDepthStencilDescriptor, DepthStencilHash>
{
private readonly MTLDevice _device;
public DepthStencilCache(MTLDevice device) {
_device = device;
}
protected override DepthStencilHash GetHash(MTLDepthStencilDescriptor descriptor) {
var hash = new DepthStencilHash();
// Front face
hash.FrontFace = new DepthStencilHash.StencilHash {
StencilFailureOperation = descriptor.FrontFaceStencil.StencilFailureOperation,
DepthFailureOperation = descriptor.FrontFaceStencil.DepthFailureOperation,
DepthStencilPassOperation = descriptor.FrontFaceStencil.DepthStencilPassOperation,
StencilCompareFunction = descriptor.FrontFaceStencil.StencilCompareFunction,
ReadMask = descriptor.FrontFaceStencil.ReadMask,
WriteMask = descriptor.FrontFaceStencil.WriteMask
};
// Back face
hash.BackFace = new DepthStencilHash.StencilHash {
StencilFailureOperation = descriptor.BackFaceStencil.StencilFailureOperation,
DepthFailureOperation = descriptor.BackFaceStencil.DepthFailureOperation,
DepthStencilPassOperation = descriptor.BackFaceStencil.DepthStencilPassOperation,
StencilCompareFunction = descriptor.BackFaceStencil.StencilCompareFunction,
ReadMask = descriptor.BackFaceStencil.ReadMask,
WriteMask = descriptor.BackFaceStencil.WriteMask
};
// Depth
hash.DepthCompareFunction = descriptor.DepthCompareFunction;
hash.DepthWriteEnabled = descriptor.DepthWriteEnabled;
return hash;
}
protected override MTLDepthStencilState CreateValue(MTLDepthStencilDescriptor descriptor)
{
return _device.NewDepthStencilState(descriptor);
}
}
}

View file

@ -16,6 +16,7 @@ namespace Ryujinx.Graphics.Metal
private readonly Pipeline _pipeline; private readonly Pipeline _pipeline;
private readonly RenderPipelineCache RenderPipelineCache; private readonly RenderPipelineCache RenderPipelineCache;
private readonly DepthStencilCache DepthStencilCache;
private EncoderState _currentState = new(); private EncoderState _currentState = new();
private EncoderState _backState = new(); private EncoderState _backState = new();
@ -32,6 +33,7 @@ namespace Ryujinx.Graphics.Metal
_device = device; _device = device;
_pipeline = pipeline; _pipeline = pipeline;
RenderPipelineCache = new(device); RenderPipelineCache = new(device);
DepthStencilCache = new(device);
} }
public void SwapStates() public void SwapStates()
@ -328,7 +330,7 @@ namespace Ryujinx.Graphics.Metal
descriptor.FrontFaceStencil = _currentState.FrontFaceStencil; descriptor.FrontFaceStencil = _currentState.FrontFaceStencil;
} }
_currentState.DepthStencilState = _device.NewDepthStencilState(descriptor); _currentState.DepthStencilState = DepthStencilCache.GetOrCreate(descriptor);
// Mark dirty // Mark dirty
_currentState.Dirty.DepthStencil = true; _currentState.Dirty.DepthStencil = true;
@ -352,7 +354,7 @@ namespace Ryujinx.Graphics.Metal
descriptor.FrontFaceStencil = _currentState.FrontFaceStencil; descriptor.FrontFaceStencil = _currentState.FrontFaceStencil;
} }
_currentState.DepthStencilState = _device.NewDepthStencilState(descriptor); _currentState.DepthStencilState = DepthStencilCache.GetOrCreate(descriptor);
// Mark dirty // Mark dirty
_currentState.Dirty.DepthStencil = true; _currentState.Dirty.DepthStencil = true;