diff options
author | mageven <62494521+mageven@users.noreply.github.com> | 2021-03-23 00:10:07 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-22 19:40:07 +0100 |
commit | 69f8722e795b0d76b84efa4de52e199e9441fca7 (patch) | |
tree | b6cbc30ea90604127d6c4a2f010b5fb756483155 /Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | |
parent | 0b022cad1e09559bd566cb90caf82ce35943752f (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.cs | 59 |
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(); } } |