Program hash set

This commit is contained in:
Isaac Marovitz 2024-09-07 12:35:37 +02:00
parent c62e00d90f
commit e81329c7b0
No known key found for this signature in database
GPG Key ID: 97250B2B09A132E1
3 changed files with 58 additions and 53 deletions

View File

@ -57,48 +57,42 @@ namespace Ryujinx.Graphics.Metal
var blitSource = ReadMsl("Blit.metal"); var blitSource = ReadMsl("Blit.metal");
var blitSourceF = blitSource.Replace("FORMAT", "float", StringComparison.Ordinal); var blitSourceF = blitSource.Replace("FORMAT", "float", StringComparison.Ordinal);
_programColorBlitF = new Program( _programColorBlitF = new Program(renderer, device, [
[
new ShaderSource(blitSourceF, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(blitSourceF, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout, device); ], blitResourceLayout);
var blitSourceI = blitSource.Replace("FORMAT", "int"); var blitSourceI = blitSource.Replace("FORMAT", "int");
_programColorBlitI = new Program( _programColorBlitI = new Program(renderer, device, [
[
new ShaderSource(blitSourceI, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(blitSourceI, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceI, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceI, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout, device); ], blitResourceLayout);
var blitSourceU = blitSource.Replace("FORMAT", "uint"); var blitSourceU = blitSource.Replace("FORMAT", "uint");
_programColorBlitU = new Program( _programColorBlitU = new Program(renderer, device, [
[
new ShaderSource(blitSourceU, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(blitSourceU, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceU, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceU, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout, device); ], blitResourceLayout);
var blitMsSource = ReadMsl("BlitMs.metal"); var blitMsSource = ReadMsl("BlitMs.metal");
var blitMsSourceF = blitMsSource.Replace("FORMAT", "float"); var blitMsSourceF = blitMsSource.Replace("FORMAT", "float");
_programColorBlitMsF = new Program( _programColorBlitMsF = new Program(renderer, device, [
[
new ShaderSource(blitMsSourceF, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(blitMsSourceF, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitMsSourceF, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitMsSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout, device); ], blitResourceLayout);
var blitMsSourceI = blitMsSource.Replace("FORMAT", "int"); var blitMsSourceI = blitMsSource.Replace("FORMAT", "int");
_programColorBlitMsI = new Program( _programColorBlitMsI = new Program(renderer, device, [
[
new ShaderSource(blitMsSourceI, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(blitMsSourceI, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitMsSourceI, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitMsSourceI, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout, device); ], blitResourceLayout);
var blitMsSourceU = blitMsSource.Replace("FORMAT", "uint"); var blitMsSourceU = blitMsSource.Replace("FORMAT", "uint");
_programColorBlitMsU = new Program( _programColorBlitMsU = new Program(renderer, device, [
[
new ShaderSource(blitMsSourceU, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(blitMsSourceU, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitMsSourceU, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitMsSourceU, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout, device); ], blitResourceLayout);
var colorClearResourceLayout = new ResourceLayoutBuilder() var colorClearResourceLayout = new ResourceLayoutBuilder()
.Add(ResourceStages.Fragment, ResourceType.UniformBuffer, 0).Build(); .Add(ResourceStages.Fragment, ResourceType.UniformBuffer, 0).Build();
@ -108,39 +102,35 @@ namespace Ryujinx.Graphics.Metal
for (int i = 0; i < Constants.MaxColorAttachments; i++) for (int i = 0; i < Constants.MaxColorAttachments; i++)
{ {
var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "float"); var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "float");
_programsColorClearF.Add(new Program( _programsColorClearF.Add(new Program(renderer, device, [
[
new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl)
], colorClearResourceLayout, device)); ], colorClearResourceLayout));
} }
for (int i = 0; i < Constants.MaxColorAttachments; i++) for (int i = 0; i < Constants.MaxColorAttachments; i++)
{ {
var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "int"); var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "int");
_programsColorClearI.Add(new Program( _programsColorClearI.Add(new Program(renderer, device, [
[
new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl)
], colorClearResourceLayout, device)); ], colorClearResourceLayout));
} }
for (int i = 0; i < Constants.MaxColorAttachments; i++) for (int i = 0; i < Constants.MaxColorAttachments; i++)
{ {
var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "uint"); var crntSource = colorClearSource.Replace("COLOR_ATTACHMENT_INDEX", i.ToString()).Replace("FORMAT", "uint");
_programsColorClearU.Add(new Program( _programsColorClearU.Add(new Program(renderer, device, [
[
new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(crntSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(crntSource, ShaderStage.Vertex, TargetLanguage.Msl)
], colorClearResourceLayout, device)); ], colorClearResourceLayout));
} }
var depthStencilClearSource = ReadMsl("DepthStencilClear.metal"); var depthStencilClearSource = ReadMsl("DepthStencilClear.metal");
_programDepthStencilClear = new Program( _programDepthStencilClear = new Program(renderer, device, [
[
new ShaderSource(depthStencilClearSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(depthStencilClearSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(depthStencilClearSource, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(depthStencilClearSource, ShaderStage.Vertex, TargetLanguage.Msl)
], colorClearResourceLayout, device); ], colorClearResourceLayout);
var strideChangeResourceLayout = new ResourceLayoutBuilder() var strideChangeResourceLayout = new ResourceLayoutBuilder()
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0) .Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
@ -148,10 +138,9 @@ namespace Ryujinx.Graphics.Metal
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build(); .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build();
var strideChangeSource = ReadMsl("ChangeBufferStride.metal"); var strideChangeSource = ReadMsl("ChangeBufferStride.metal");
_programStrideChange = new Program( _programStrideChange = new Program(renderer, device, [
[
new ShaderSource(strideChangeSource, ShaderStage.Compute, TargetLanguage.Msl) new ShaderSource(strideChangeSource, ShaderStage.Compute, TargetLanguage.Msl)
], strideChangeResourceLayout, device, new ComputeSize(64, 1, 1)); ], strideChangeResourceLayout, new ComputeSize(64, 1, 1));
var convertD32S8ToD24S8ResourceLayout = new ResourceLayoutBuilder() var convertD32S8ToD24S8ResourceLayout = new ResourceLayoutBuilder()
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0) .Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
@ -159,10 +148,9 @@ namespace Ryujinx.Graphics.Metal
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build(); .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build();
var convertD32S8ToD24S8Source = ReadMsl("ConvertD32S8ToD24S8.metal"); var convertD32S8ToD24S8Source = ReadMsl("ConvertD32S8ToD24S8.metal");
_programConvertD32S8ToD24S8 = new Program( _programConvertD32S8ToD24S8 = new Program(renderer, device, [
[
new ShaderSource(convertD32S8ToD24S8Source, ShaderStage.Compute, TargetLanguage.Msl) new ShaderSource(convertD32S8ToD24S8Source, ShaderStage.Compute, TargetLanguage.Msl)
], convertD32S8ToD24S8ResourceLayout, device, new ComputeSize(64, 1, 1)); ], convertD32S8ToD24S8ResourceLayout, new ComputeSize(64, 1, 1));
var convertIndexBufferLayout = new ResourceLayoutBuilder() var convertIndexBufferLayout = new ResourceLayoutBuilder()
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1) .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1)
@ -170,38 +158,33 @@ namespace Ryujinx.Graphics.Metal
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 3).Build(); .Add(ResourceStages.Compute, ResourceType.StorageBuffer, 3).Build();
var convertIndexBufferSource = ReadMsl("ConvertIndexBuffer.metal"); var convertIndexBufferSource = ReadMsl("ConvertIndexBuffer.metal");
_programConvertIndexBuffer = new Program( _programConvertIndexBuffer = new Program(renderer, device, [
[
new ShaderSource(convertIndexBufferSource, ShaderStage.Compute, TargetLanguage.Msl) new ShaderSource(convertIndexBufferSource, ShaderStage.Compute, TargetLanguage.Msl)
], convertIndexBufferLayout, device, new ComputeSize(16, 1, 1)); ], convertIndexBufferLayout, new ComputeSize(16, 1, 1));
var depthBlitSource = ReadMsl("DepthBlit.metal"); var depthBlitSource = ReadMsl("DepthBlit.metal");
_programDepthBlit = new Program( _programDepthBlit = new Program(renderer, device, [
[
new ShaderSource(depthBlitSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(depthBlitSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout, device); ], blitResourceLayout);
var depthBlitMsSource = ReadMsl("DepthBlitMs.metal"); var depthBlitMsSource = ReadMsl("DepthBlitMs.metal");
_programDepthBlitMs = new Program( _programDepthBlitMs = new Program(renderer, device, [
[
new ShaderSource(depthBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(depthBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout, device); ], blitResourceLayout);
var stencilBlitSource = ReadMsl("StencilBlit.metal"); var stencilBlitSource = ReadMsl("StencilBlit.metal");
_programStencilBlit = new Program( _programStencilBlit = new Program(renderer, device, [
[
new ShaderSource(stencilBlitSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(stencilBlitSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout, device); ], blitResourceLayout);
var stencilBlitMsSource = ReadMsl("StencilBlitMs.metal"); var stencilBlitMsSource = ReadMsl("StencilBlitMs.metal");
_programStencilBlitMs = new Program( _programStencilBlitMs = new Program(renderer, device, [
[
new ShaderSource(stencilBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl), new ShaderSource(stencilBlitMsSource, ShaderStage.Fragment, TargetLanguage.Msl),
new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl) new ShaderSource(blitSourceF, ShaderStage.Vertex, TargetLanguage.Msl)
], blitResourceLayout, device); ], blitResourceLayout);
} }
private static string ReadMsl(string fileName) private static string ReadMsl(string fileName)

View File

@ -34,11 +34,13 @@ namespace Ryujinx.Graphics.Metal
internal Action<Action> InterruptAction { get; private set; } internal Action<Action> InterruptAction { get; private set; }
internal SyncManager SyncManager { get; private set; } internal SyncManager SyncManager { get; private set; }
internal HashSet<Program> Programs { get; }
internal HashSet<SamplerHolder> Samplers { get; } internal HashSet<SamplerHolder> Samplers { get; }
public MetalRenderer(Func<CAMetalLayer> metalLayer) public MetalRenderer(Func<CAMetalLayer> metalLayer)
{ {
_device = MTLDevice.CreateSystemDefaultDevice(); _device = MTLDevice.CreateSystemDefaultDevice();
Programs = new HashSet<Program>();
Samplers = new HashSet<SamplerHolder>(); Samplers = new HashSet<SamplerHolder>();
if (_device.ArgumentBuffersSupport != MTLArgumentBuffersTier.Tier2) if (_device.ArgumentBuffersSupport != MTLArgumentBuffersTier.Tier2)
@ -100,7 +102,7 @@ namespace Ryujinx.Graphics.Metal
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info) public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
{ {
return new Program(shaders, info.ResourceLayout, _device, info.ComputeLocalSize); return new Program(this, _device, shaders, info.ResourceLayout, info.ComputeLocalSize);
} }
public ISampler CreateSampler(SamplerCreateInfo info) public ISampler CreateSampler(SamplerCreateInfo info)
@ -286,6 +288,11 @@ namespace Ryujinx.Graphics.Metal
{ {
BackgroundResources.Dispose(); BackgroundResources.Dispose();
foreach (var program in Programs)
{
program.Dispose();
}
foreach (var sampler in Samplers) foreach (var sampler in Samplers)
{ {
sampler.Dispose(); sampler.Dispose();

View File

@ -19,6 +19,8 @@ namespace Ryujinx.Graphics.Metal
private readonly GCHandle[] _handles; private readonly GCHandle[] _handles;
private int _successCount; private int _successCount;
private readonly MetalRenderer _renderer;
public MTLFunction VertexFunction; public MTLFunction VertexFunction;
public MTLFunction FragmentFunction; public MTLFunction FragmentFunction;
public MTLFunction ComputeFunction; public MTLFunction ComputeFunction;
@ -34,8 +36,16 @@ namespace Ryujinx.Graphics.Metal
// Argument buffer sizes for Fragment stage // Argument buffer sizes for Fragment stage
public int[] FragArgumentBufferSizes { get; } public int[] FragArgumentBufferSizes { get; }
public Program(ShaderSource[] shaders, ResourceLayout resourceLayout, MTLDevice device, ComputeSize computeLocalSize = default) public Program(
MetalRenderer renderer,
MTLDevice device,
ShaderSource[] shaders,
ResourceLayout resourceLayout,
ComputeSize computeLocalSize = default)
{ {
_renderer = renderer;
renderer.Programs.Add(this);
ComputeLocalSize = computeLocalSize; ComputeLocalSize = computeLocalSize;
_shaders = shaders; _shaders = shaders;
_handles = new GCHandle[_shaders.Length]; _handles = new GCHandle[_shaders.Length];
@ -253,6 +263,11 @@ namespace Ryujinx.Graphics.Metal
public void Dispose() public void Dispose()
{ {
if (!_renderer.Programs.Remove(this))
{
return;
}
if (_graphicsPipelineCache != null) if (_graphicsPipelineCache != null)
{ {
foreach (MTLRenderPipelineState pipeline in _graphicsPipelineCache.Values) foreach (MTLRenderPipelineState pipeline in _graphicsPipelineCache.Values)