aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
diff options
context:
space:
mode:
authormageven <62494521+mageven@users.noreply.github.com>2021-03-23 00:10:07 +0530
committerGitHub <noreply@github.com>2021-03-22 19:40:07 +0100
commit69f8722e795b0d76b84efa4de52e199e9441fca7 (patch)
treeb6cbc30ea90604127d6c4a2f010b5fb756483155 /Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
parent0b022cad1e09559bd566cb90caf82ce35943752f (diff)
Fix inconsistencies in progress reporting (#2129)
Signal and setup events correctly Eliminate possible races Use a single event Mark volatiles and reduce scope of waithandles Common handler 100ms -> 50ms
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs')
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs59
1 files changed, 40 insertions, 19 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
index a085936a..d99a402b 100644
--- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
@@ -38,10 +38,9 @@ namespace Ryujinx.Graphics.Gpu.Shader
private const ulong ShaderCodeGenVersion = 2088;
// Progress reporting helpers
- private int _shaderCount;
- private readonly AutoResetEvent _progressReportEvent;
- public event Action<bool> ShaderCacheStateChanged;
- public event Action<int, int> ShaderCacheProgressChanged;
+ private volatile int _shaderCount;
+ private volatile int _totalShaderCount;
+ public event Action<ShaderCacheState, int, int> ShaderCacheStateChanged;
/// <summary>
/// Creates a new instance of the shader cache.
@@ -57,8 +56,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
_gpPrograms = new Dictionary<ShaderAddresses, List<ShaderBundle>>();
_gpProgramsDiskCache = new Dictionary<Hash128, ShaderBundle>();
_cpProgramsDiskCache = new Dictionary<Hash128, ShaderBundle>();
-
- _progressReportEvent = new AutoResetEvent(false);
}
/// <summary>
@@ -85,11 +82,25 @@ namespace Ryujinx.Graphics.Gpu.Shader
ReadOnlySpan<Hash128> guestProgramList = _cacheManager.GetGuestProgramList();
- _progressReportEvent.Reset();
+ using AutoResetEvent progressReportEvent = new AutoResetEvent(false);
+
_shaderCount = 0;
+ _totalShaderCount = guestProgramList.Length;
- ShaderCacheStateChanged?.Invoke(true);
- ThreadPool.QueueUserWorkItem(ProgressLogger, guestProgramList.Length);
+ ShaderCacheStateChanged?.Invoke(ShaderCacheState.Start, _shaderCount, _totalShaderCount);
+ Thread progressReportThread = null;
+
+ if (guestProgramList.Length > 0)
+ {
+ progressReportThread = new Thread(ReportProgress)
+ {
+ Name = "ShaderCache.ProgressReporter",
+ Priority = ThreadPriority.Lowest,
+ IsBackground = true
+ };
+
+ progressReportThread.Start(progressReportEvent);
+ }
for (int programIndex = 0; programIndex < guestProgramList.Length; programIndex++)
{
@@ -318,7 +329,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
_gpProgramsDiskCache.Add(key, new ShaderBundle(hostProgram, shaders));
}
- _shaderCount = programIndex;
+ _shaderCount = programIndex + 1;
}
if (!isReadOnly)
@@ -329,26 +340,37 @@ namespace Ryujinx.Graphics.Gpu.Shader
_cacheManager.Synchronize();
}
- _progressReportEvent.Set();
- ShaderCacheStateChanged?.Invoke(false);
+ progressReportEvent.Set();
+ progressReportThread?.Join();
+
+ ShaderCacheStateChanged?.Invoke(ShaderCacheState.Loaded, _shaderCount, _totalShaderCount);
Logger.Info?.Print(LogClass.Gpu, $"Shader cache loaded {_shaderCount} entries.");
}
}
/// <summary>
- /// Raises ShaderCacheProgressChanged events periodically.
+ /// Raises ShaderCacheStateChanged events periodically.
/// </summary>
- private void ProgressLogger(object state)
+ private void ReportProgress(object state)
{
- const int refreshRate = 100; // ms
+ const int refreshRate = 50; // ms
+
+ AutoResetEvent endEvent = (AutoResetEvent)state;
+
+ int count = 0;
- int totalCount = (int)state;
do
{
- ShaderCacheProgressChanged?.Invoke(_shaderCount, totalCount);
+ int newCount = _shaderCount;
+
+ if (count != newCount)
+ {
+ ShaderCacheStateChanged?.Invoke(ShaderCacheState.Loading, newCount, _totalShaderCount);
+ count = newCount;
+ }
}
- while (!_progressReportEvent.WaitOne(refreshRate));
+ while (!endEvent.WaitOne(refreshRate));
}
/// <summary>
@@ -833,7 +855,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
}
}
- _progressReportEvent?.Dispose();
_cacheManager?.Dispose();
}
}