A game about forced loneliness, made by TACStudios
at master 109 lines 3.9 kB view raw
1using System.Collections.Generic; 2using UnityEngine.Rendering; 3using UnityEngine.Rendering.RenderGraphModule; 4using UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler; 5 6class RenderGraphCompilationCache 7{ 8 struct HashEntry<T> 9 { 10 public int hash; 11 public int lastFrameUsed; 12 public T compiledGraph; 13 } 14 15 DynamicArray<HashEntry<RenderGraph.CompiledGraph>> m_HashEntries = new(); 16 DynamicArray<HashEntry<CompilerContextData>> m_NativeHashEntries = new(); 17 18 Stack<RenderGraph.CompiledGraph> m_CompiledGraphPool = new(); 19 Stack<CompilerContextData> m_NativeCompiledGraphPool = new(); 20 21 static int HashEntryComparer<T>(HashEntry<T> a, HashEntry<T> b) 22 { 23 if (a.lastFrameUsed < b.lastFrameUsed) 24 return -1; 25 else if (a.lastFrameUsed > b.lastFrameUsed) 26 return 1; 27 else 28 return 0; 29 } 30 31 static DynamicArray<HashEntry<RenderGraph.CompiledGraph>>.SortComparer s_EntryComparer = HashEntryComparer<RenderGraph.CompiledGraph>; 32 static DynamicArray<HashEntry<CompilerContextData>>.SortComparer s_NativeEntryComparer = HashEntryComparer<CompilerContextData>; 33 34 const int k_CachedGraphCount = 20; 35 36 public RenderGraphCompilationCache() 37 { 38 for (int i = 0; i < k_CachedGraphCount; ++i) 39 { 40 m_CompiledGraphPool.Push(new RenderGraph.CompiledGraph()); 41 m_NativeCompiledGraphPool.Push(new CompilerContextData(NativePassCompiler.k_EstimatedPassCount)); 42 } 43 } 44 45 // Avoid GC in lambda. 46 static int s_Hash; 47 48 bool GetCompilationCache<T>(int hash, int frameIndex, out T outGraph, DynamicArray<HashEntry<T>> hashEntries, Stack<T> pool, DynamicArray<HashEntry<T>>.SortComparer comparer) 49 where T : RenderGraph.ICompiledGraph 50 { 51 s_Hash = hash; 52 int index = hashEntries.FindIndex(0, hashEntries.size, (value) => value.hash == s_Hash); 53 if (index != -1) 54 { 55 ref var entry = ref hashEntries[index]; 56 outGraph = entry.compiledGraph; 57 entry.lastFrameUsed = frameIndex; 58 return true; 59 } 60 else 61 { 62 if (pool.Count != 0) 63 { 64 var newEntry = new HashEntry<T>() 65 { 66 hash = hash, 67 lastFrameUsed = frameIndex, 68 compiledGraph = pool.Pop() 69 }; 70 hashEntries.Add(newEntry); 71 outGraph = newEntry.compiledGraph; 72 return false; 73 } 74 else 75 { 76 // Reuse the oldest one. 77 hashEntries.QuickSort(comparer); 78 ref var oldestEntry = ref hashEntries[0]; 79 oldestEntry.hash = hash; 80 oldestEntry.lastFrameUsed = frameIndex; 81 oldestEntry.compiledGraph.Clear(); 82 83 outGraph = oldestEntry.compiledGraph; 84 return false; 85 } 86 } 87 } 88 89 public bool GetCompilationCache(int hash, int frameIndex, out RenderGraph.CompiledGraph outGraph) 90 { 91 return GetCompilationCache(hash, frameIndex, out outGraph, m_HashEntries, m_CompiledGraphPool, s_EntryComparer); 92 } 93 94 public bool GetCompilationCache(int hash, int frameIndex, out CompilerContextData outGraph) 95 { 96 return GetCompilationCache(hash, frameIndex, out outGraph, m_NativeHashEntries, m_NativeCompiledGraphPool, s_NativeEntryComparer); 97 } 98 99 public void Clear() 100 { 101 for (int i = 0; i < m_HashEntries.size; ++i) 102 m_CompiledGraphPool.Push(m_HashEntries[i].compiledGraph); 103 m_HashEntries.Clear(); 104 105 for (int i = 0; i < m_NativeHashEntries.size; ++i) 106 m_NativeCompiledGraphPool.Push(m_NativeHashEntries[i].compiledGraph); 107 m_NativeHashEntries.Clear(); 108 } 109}