State and cache optimization (#27)

* WIP pipeline/depth state cache rework

* Fix some issues

* Fix some more default values

* Reduce allocations for state changes

* fix helpershader stuff

* explanation comment

* fix depth bias
This commit is contained in:
riperiperi 2024-06-28 21:14:53 +01:00 committed by Isaac Marovitz
parent 9d26aa8d06
commit e02df72323
14 changed files with 1142 additions and 565 deletions

View file

@ -16,6 +16,10 @@ namespace Ryujinx.Graphics.Metal
public MTLFunction FragmentFunction;
public MTLFunction ComputeFunction;
private HashTableSlim<PipelineUid, MTLRenderPipelineState> _graphicsPipelineCache;
private MTLComputePipelineState? _computePipelineCache;
private bool _firstBackgroundUse;
public Program(ShaderSource[] shaders, MTLDevice device)
{
for (int index = 0; index < shaders.Length; index++)
@ -62,8 +66,64 @@ namespace Ryujinx.Graphics.Metal
return ""u8.ToArray();
}
public void AddGraphicsPipeline(ref PipelineUid key, MTLRenderPipelineState pipeline)
{
(_graphicsPipelineCache ??= new()).Add(ref key, pipeline);
}
public void AddComputePipeline(MTLComputePipelineState pipeline)
{
_computePipelineCache = pipeline;
}
public bool TryGetGraphicsPipeline(ref PipelineUid key, out MTLRenderPipelineState pipeline)
{
if (_graphicsPipelineCache == null)
{
pipeline = default;
return false;
}
if (!_graphicsPipelineCache.TryGetValue(ref key, out pipeline))
{
if (_firstBackgroundUse)
{
Logger.Warning?.Print(LogClass.Gpu, "Background pipeline compile missed on draw - incorrect pipeline state?");
_firstBackgroundUse = false;
}
return false;
}
_firstBackgroundUse = false;
return true;
}
public bool TryGetComputePipeline(out MTLComputePipelineState pipeline)
{
if (_computePipelineCache.HasValue)
{
pipeline = _computePipelineCache.Value;
return true;
}
pipeline = default;
return false;
}
public void Dispose()
{
if (_graphicsPipelineCache != null)
{
foreach (MTLRenderPipelineState pipeline in _graphicsPipelineCache.Values)
{
pipeline.Dispose();
}
}
_computePipelineCache?.Dispose();
VertexFunction.Dispose();
FragmentFunction.Dispose();
ComputeFunction.Dispose();