using Ryujinx.Graphics.Gpu.Shader.HashTable; using System.Collections.Generic; namespace Ryujinx.Graphics.Gpu.Shader { /// /// Compute shader cache hash table. /// class ComputeShaderCacheHashTable { private readonly PartitionedHashTable _cache; private readonly List _shaderPrograms; /// /// Creates a new compute shader cache hash table. /// public ComputeShaderCacheHashTable() { _cache = new PartitionedHashTable(); _shaderPrograms = new List(); } /// /// Adds a program to the cache. /// /// Program to be added public void Add(CachedShaderProgram program) { var specList = _cache.GetOrAdd(program.Shaders[0].Code, new ShaderSpecializationList()); specList.Add(program); _shaderPrograms.Add(program); } /// /// Tries to find a cached program. /// /// GPU channel /// Texture pool state /// Compute state /// GPU virtual address of the compute shader /// Cached host program for the given state, if found /// Cached guest code, if any found /// True if a cached host program was found, false otherwise public bool TryFind( GpuChannel channel, GpuChannelPoolState poolState, GpuChannelComputeState computeState, ulong gpuVa, out CachedShaderProgram program, out byte[] cachedGuestCode) { program = null; ShaderCodeAccessor codeAccessor = new ShaderCodeAccessor(channel.MemoryManager, gpuVa); bool hasSpecList = _cache.TryFindItem(codeAccessor, out var specList, out cachedGuestCode); return hasSpecList && specList.TryFindForCompute(channel, poolState, computeState, out program); } /// /// Gets all programs that have been added to the table. /// /// Programs added to the table public IEnumerable GetPrograms() { foreach (var program in _shaderPrograms) { yield return program; } } } }