/ src / Ryujinx.Graphics.Gpu / Shader / ComputeShaderCacheHashTable.cs
ComputeShaderCacheHashTable.cs
 1  using Ryujinx.Graphics.Gpu.Shader.HashTable;
 2  using System.Collections.Generic;
 3  
 4  namespace Ryujinx.Graphics.Gpu.Shader
 5  {
 6      /// <summary>
 7      /// Compute shader cache hash table.
 8      /// </summary>
 9      class ComputeShaderCacheHashTable
10      {
11          private readonly PartitionedHashTable<ShaderSpecializationList> _cache;
12          private readonly List<CachedShaderProgram> _shaderPrograms;
13  
14          /// <summary>
15          /// Creates a new compute shader cache hash table.
16          /// </summary>
17          public ComputeShaderCacheHashTable()
18          {
19              _cache = new PartitionedHashTable<ShaderSpecializationList>();
20              _shaderPrograms = new List<CachedShaderProgram>();
21          }
22  
23          /// <summary>
24          /// Adds a program to the cache.
25          /// </summary>
26          /// <param name="program">Program to be added</param>
27          public void Add(CachedShaderProgram program)
28          {
29              var specList = _cache.GetOrAdd(program.Shaders[0].Code, new ShaderSpecializationList());
30              specList.Add(program);
31              _shaderPrograms.Add(program);
32          }
33  
34          /// <summary>
35          /// Tries to find a cached program.
36          /// </summary>
37          /// <param name="channel">GPU channel</param>
38          /// <param name="poolState">Texture pool state</param>
39          /// <param name="computeState">Compute state</param>
40          /// <param name="gpuVa">GPU virtual address of the compute shader</param>
41          /// <param name="program">Cached host program for the given state, if found</param>
42          /// <param name="cachedGuestCode">Cached guest code, if any found</param>
43          /// <returns>True if a cached host program was found, false otherwise</returns>
44          public bool TryFind(
45              GpuChannel channel,
46              GpuChannelPoolState poolState,
47              GpuChannelComputeState computeState,
48              ulong gpuVa,
49              out CachedShaderProgram program,
50              out byte[] cachedGuestCode)
51          {
52              program = null;
53              ShaderCodeAccessor codeAccessor = new(channel.MemoryManager, gpuVa);
54              bool hasSpecList = _cache.TryFindItem(codeAccessor, out var specList, out cachedGuestCode);
55  
56              return hasSpecList && specList.TryFindForCompute(channel, poolState, computeState, out program);
57          }
58  
59          /// <summary>
60          /// Gets all programs that have been added to the table.
61          /// </summary>
62          /// <returns>Programs added to the table</returns>
63          public IEnumerable<CachedShaderProgram> GetPrograms()
64          {
65              foreach (var program in _shaderPrograms)
66              {
67                  yield return program;
68              }
69          }
70      }
71  }