diff options
| author | riperiperi <rhy3756547@hotmail.com> | 2021-04-02 23:05:55 +0100 |
|---|---|---|
| committer | riperiperi <rhy3756547@hotmail.com> | 2021-04-18 17:33:59 +0100 |
| commit | a0aa09912cb8f35ae06834b08308a128886f207f (patch) | |
| tree | b1175d7dc58b22e8b6e638c8663a706d96890f19 | |
| parent | 20d560e3f925e387c9c28705a120202ca38abd8b (diff) | |
Use event to wake the main thread on task completion
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | 12 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/ShaderCompileTask.cs | 13 |
2 files changed, 22 insertions, 3 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index 35908cb9..5ee41cdf 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -110,6 +110,8 @@ namespace Ryujinx.Graphics.Gpu.Shader int programIndex = 0; List<ShaderCompileTask> activeTasks = new List<ShaderCompileTask>(); + AutoResetEvent taskDoneEvent = new AutoResetEvent(false); + // This thread dispatches tasks to do shader translation, and creates programs that OpenGL will link in the background. // The program link status is checked in a non-blocking manner so that multiple shaders can be compiled at once. @@ -158,7 +160,7 @@ namespace Ryujinx.Graphics.Gpu.Shader hostProgram = _context.Renderer.LoadProgramBinary(hostProgramBinary); } - ShaderCompileTask task = new ShaderCompileTask(); + ShaderCompileTask task = new ShaderCompileTask(taskDoneEvent); activeTasks.Add(task); task.OnCompiled(hostProgram, (bool isHostProgramValid, ShaderCompileTask task) => @@ -261,7 +263,7 @@ namespace Ryujinx.Graphics.Gpu.Shader hostProgram = _context.Renderer.LoadProgramBinary(hostProgramBinary); } - ShaderCompileTask task = new ShaderCompileTask(); + ShaderCompileTask task = new ShaderCompileTask(taskDoneEvent); activeTasks.Add(task); GuestShaderCacheEntry[] entries = cachedShaderEntries.ToArray(); @@ -412,7 +414,11 @@ namespace Ryujinx.Graphics.Gpu.Shader if (activeTasks.Count == maxTaskCount) { - Thread.Sleep(1); + // Wait for a task to be done, or for 1ms. + // Host shader compilation cannot signal when it is done, + // so the 1ms timeout is required to poll status. + + taskDoneEvent.WaitOne(1); } } diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCompileTask.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCompileTask.cs index cc1b322b..ff48fab0 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCompileTask.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCompileTask.cs @@ -1,5 +1,6 @@ using Ryujinx.Graphics.GAL; using System; +using System.Threading; using System.Threading.Tasks; namespace Ryujinx.Graphics.Gpu.Shader @@ -17,6 +18,16 @@ namespace Ryujinx.Graphics.Gpu.Shader private IProgram _program; private ShaderCompileTaskCallback _action; + private AutoResetEvent _taskDoneEvent; + + /// <summary> + /// Create a new shader compile task, with an event to signal whenever a subtask completes. + /// </summary> + /// <param name="taskDoneEvent">Event to signal when a subtask completes</param> + public ShaderCompileTask(AutoResetEvent taskDoneEvent) + { + _taskDoneEvent = taskDoneEvent; + } /// <summary> /// Check the completion status of the shader compile task, and run callbacks on step completion. @@ -58,6 +69,8 @@ namespace Ryujinx.Graphics.Gpu.Shader _programsTask = task; _action = action; + + task.ContinueWith(task => _taskDoneEvent.Set()); } /// <summary> |
