using System.Collections; using System.Collections.Generic; namespace Ryujinx.Graphics.Gpu.Shader { /// /// List of cached shader programs that differs only by specialization state. /// class ShaderSpecializationList : IEnumerable { private readonly List _entries = new(); /// /// Adds a program to the list. /// /// Program to be added public void Add(CachedShaderProgram program) { _entries.Add(program); } /// /// Tries to find an existing 3D program on the cache. /// /// GPU channel /// Texture pool state /// Graphics state /// Cached program, if found /// True if a compatible program is found, false otherwise public bool TryFindForGraphics( GpuChannel channel, ref GpuChannelPoolState poolState, ref GpuChannelGraphicsState graphicsState, out CachedShaderProgram program) { foreach (var entry in _entries) { bool usesDrawParameters = entry.Shaders[1]?.Info.UsesDrawParameters ?? false; if (entry.SpecializationState.MatchesGraphics(channel, ref poolState, ref graphicsState, usesDrawParameters, true)) { program = entry; return true; } } program = default; return false; } /// /// Tries to find an existing compute program on the cache. /// /// GPU channel /// Texture pool state /// Compute state /// Cached program, if found /// True if a compatible program is found, false otherwise public bool TryFindForCompute(GpuChannel channel, GpuChannelPoolState poolState, GpuChannelComputeState computeState, out CachedShaderProgram program) { foreach (var entry in _entries) { if (entry.SpecializationState.MatchesCompute(channel, ref poolState, computeState, true)) { program = entry; return true; } } program = default; return false; } public IEnumerator GetEnumerator() { return _entries.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }