diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index 91edbf2a..e5289bc0 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -35,6 +35,8 @@ namespace Ryujinx.Graphics.Gpu.Shader private Dictionary<Hash128, ShaderBundle> _gpProgramsDiskCache; private Dictionary<Hash128, ShaderBundle> _cpProgramsDiskCache; + private Queue<(IProgram, Action<byte[]>)> _programsToSaveQueue; + /// <summary> /// Version of the codegen (to be changed when codegen or guest format change). /// </summary> @@ -59,6 +61,31 @@ namespace Ryujinx.Graphics.Gpu.Shader _gpPrograms = new Dictionary<ShaderAddresses, List<ShaderBundle>>(); _gpProgramsDiskCache = new Dictionary<Hash128, ShaderBundle>(); _cpProgramsDiskCache = new Dictionary<Hash128, ShaderBundle>(); + + _programsToSaveQueue = new Queue<(IProgram, Action<byte[]>)>(); + } + + /// <summary> + /// Processes the queue of shaders that must save their binaries to the disk cache. + /// </summary> + public void ProcessShaderCacheQueue() + { + // Check to see if the binaries for previously compiled shaders are ready, and save them out. + + while (_programsToSaveQueue.Count > 0) + { + (IProgram program, Action<byte[]> dataAction) = _programsToSaveQueue.Peek(); + + if (program.CheckProgramLink(false) != ProgramLinkStatus.Incomplete) + { + dataAction(program.GetBinary()); + _programsToSaveQueue.Dequeue(); + } + else + { + break; + } + } } /// <summary> @@ -597,10 +624,6 @@ namespace Ryujinx.Graphics.Gpu.Shader IProgram hostProgram = _context.Renderer.CreateProgram(new IShader[] { shader.HostShader }, null); - hostProgram.CheckProgramLink(true); - - byte[] hostProgramBinary = HostShaderCacheEntry.Create(hostProgram.GetBinary(), new ShaderCodeHolder[] { shader }); - cpShader = new ShaderBundle(hostProgram, shader); if (isShaderCacheEnabled) @@ -609,7 +632,11 @@ namespace Ryujinx.Graphics.Gpu.Shader if (!isShaderCacheReadOnly) { - _cacheManager.SaveProgram(ref programCodeHash, CacheHelper.CreateGuestProgramDump(shaderCacheEntries), hostProgramBinary); + byte[] guestProgramDump = CacheHelper.CreateGuestProgramDump(shaderCacheEntries); + _programsToSaveQueue.Enqueue((hostProgram, (byte[] hostProgramBinary) => + { + _cacheManager.SaveProgram(ref programCodeHash, guestProgramDump, HostShaderCacheEntry.Create(hostProgramBinary, new ShaderCodeHolder[] { shader })); + })); } } } @@ -740,10 +767,6 @@ namespace Ryujinx.Graphics.Gpu.Shader IProgram hostProgram = _context.Renderer.CreateProgram(hostShaders.ToArray(), tfd); - hostProgram.CheckProgramLink(true); - - byte[] hostProgramBinary = HostShaderCacheEntry.Create(hostProgram.GetBinary(), shaders); - gpShaders = new ShaderBundle(hostProgram, shaders); if (isShaderCacheEnabled) @@ -752,7 +775,11 @@ namespace Ryujinx.Graphics.Gpu.Shader if (!isShaderCacheReadOnly) { - _cacheManager.SaveProgram(ref programCodeHash, CacheHelper.CreateGuestProgramDump(shaderCacheEntries, tfd), hostProgramBinary); + byte[] guestProgramDump = CacheHelper.CreateGuestProgramDump(shaderCacheEntries, tfd); + _programsToSaveQueue.Enqueue((hostProgram, (byte[] hostProgramBinary) => + { + _cacheManager.SaveProgram(ref programCodeHash, guestProgramDump, HostShaderCacheEntry.Create(hostProgramBinary, shaders)); + })); } } } |