aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs')
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs47
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));
+ }));
}
}
}