From 870d9599cc056e515dd63620fd10bf9fee4992ee Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 18 Jan 2024 14:17:38 -0300 Subject: [PATCH] Change shader cache init wait method (#6131) * Change shader cache init wait method * Make field readonly --- src/ARMeilleure/Translation/Translator.cs | 5 ----- src/Ryujinx.Ava/AppHost.cs | 2 -- src/Ryujinx.Graphics.Gpu/GpuContext.cs | 18 ++++++++++++++++-- src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | 3 ++- src/Ryujinx.HLE/HOS/ArmProcessContext.cs | 2 ++ src/Ryujinx.Headless.SDL2/Program.cs | 4 ---- src/Ryujinx.Headless.SDL2/WindowBase.cs | 2 -- src/Ryujinx.Tests/Cpu/CpuTest.cs | 1 - src/Ryujinx.Tests/Cpu/CpuTest32.cs | 1 - src/Ryujinx/Ui/MainWindow.cs | 3 --- src/Ryujinx/Ui/RendererWidgetBase.cs | 2 -- 11 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs index 7f6a25b0..48c1a575 100644 --- a/src/ARMeilleure/Translation/Translator.cs +++ b/src/ARMeilleure/Translation/Translator.cs @@ -57,9 +57,6 @@ namespace ARMeilleure.Translation private Thread[] _backgroundTranslationThreads; private volatile int _threadCount; - // FIXME: Remove this once the init logic of the emulator will be redone. - public static readonly ManualResetEvent IsReadyForTranslation = new(false); - public Translator(IJitMemoryAllocator allocator, IMemoryManager memory, bool for64Bits) { _allocator = allocator; @@ -100,8 +97,6 @@ namespace ARMeilleure.Translation { if (Interlocked.Increment(ref _threadCount) == 1) { - IsReadyForTranslation.WaitOne(); - if (_ptc.State == PtcState.Enabled) { Debug.Assert(Functions.Count == 0); diff --git a/src/Ryujinx.Ava/AppHost.cs b/src/Ryujinx.Ava/AppHost.cs index 2fd9ce00..e434deb0 100644 --- a/src/Ryujinx.Ava/AppHost.cs +++ b/src/Ryujinx.Ava/AppHost.cs @@ -1,4 +1,3 @@ -using ARMeilleure.Translation; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; @@ -916,7 +915,6 @@ namespace Ryujinx.Ava { Device.Gpu.SetGpuThread(); Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token); - Translator.IsReadyForTranslation.Set(); _renderer.Window.ChangeVSyncMode(Device.EnableDeviceVsync); diff --git a/src/Ryujinx.Graphics.Gpu/GpuContext.cs b/src/Ryujinx.Graphics.Gpu/GpuContext.cs index a50852b0..aaf03ff7 100644 --- a/src/Ryujinx.Graphics.Gpu/GpuContext.cs +++ b/src/Ryujinx.Graphics.Gpu/GpuContext.cs @@ -106,6 +106,8 @@ namespace Ryujinx.Graphics.Gpu private long _modifiedSequence; private readonly ulong _firstTimestamp; + private readonly ManualResetEvent _gpuReadyEvent; + /// /// Creates a new instance of the GPU emulation context. /// @@ -121,6 +123,7 @@ namespace Ryujinx.Graphics.Gpu Window = new Window(this); HostInitalized = new ManualResetEvent(false); + _gpuReadyEvent = new ManualResetEvent(false); SyncActions = new List(); SyncpointActions = new List(); @@ -216,7 +219,7 @@ namespace Ryujinx.Graphics.Gpu /// Gets a sequence number for resource modification ordering. This increments on each call. /// /// A sequence number for resource modification ordering - public long GetModifiedSequence() + internal long GetModifiedSequence() { return _modifiedSequence++; } @@ -225,7 +228,7 @@ namespace Ryujinx.Graphics.Gpu /// Gets the value of the GPU timer. /// /// The current GPU timestamp - public ulong GetTimestamp() + internal ulong GetTimestamp() { // Guest timestamp will start at 0, instead of host value. ulong ticks = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds) - _firstTimestamp; @@ -262,6 +265,16 @@ namespace Ryujinx.Graphics.Gpu { physicalMemory.ShaderCache.Initialize(cancellationToken); } + + _gpuReadyEvent.Set(); + } + + /// + /// Waits until the GPU is ready to receive commands. + /// + public void WaitUntilGpuReady() + { + _gpuReadyEvent.WaitOne(); } /// @@ -399,6 +412,7 @@ namespace Ryujinx.Graphics.Gpu { GPFifo.Dispose(); HostInitalized.Dispose(); + _gpuReadyEvent.Dispose(); // Has to be disposed before processing deferred actions, as it will produce some. foreach (var physicalMemory in PhysicalMemoryRegistry.Values) diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index af682e42..0b17af8b 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -161,7 +161,8 @@ namespace Ryujinx.Graphics.Gpu.Shader _graphicsShaderCache, _computeShaderCache, _diskCacheHostStorage, - ShaderCacheStateUpdate, cancellationToken); + ShaderCacheStateUpdate, + cancellationToken); loader.LoadShaders(); diff --git a/src/Ryujinx.HLE/HOS/ArmProcessContext.cs b/src/Ryujinx.HLE/HOS/ArmProcessContext.cs index ff218546..4de00978 100644 --- a/src/Ryujinx.HLE/HOS/ArmProcessContext.cs +++ b/src/Ryujinx.HLE/HOS/ArmProcessContext.cs @@ -57,6 +57,8 @@ namespace Ryujinx.HLE.HOS public void Execute(IExecutionContext context, ulong codeAddress) { + // We must wait until shader cache is loaded, among other things, before executing CPU code. + _gpuContext.WaitUntilGpuReady(); _cpuContext.Execute(context, codeAddress); } diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs index 7e3c79f5..e545079b 100644 --- a/src/Ryujinx.Headless.SDL2/Program.cs +++ b/src/Ryujinx.Headless.SDL2/Program.cs @@ -1,4 +1,3 @@ -using ARMeilleure.Translation; using CommandLine; using LibHac.Tools.FsSystem; using Ryujinx.Audio.Backends.SDL2; @@ -710,9 +709,6 @@ namespace Ryujinx.Headless.SDL2 } SetupProgressHandler(); - - Translator.IsReadyForTranslation.Reset(); - ExecutionEntrypoint(); return true; diff --git a/src/Ryujinx.Headless.SDL2/WindowBase.cs b/src/Ryujinx.Headless.SDL2/WindowBase.cs index adab0764..1bfe4312 100644 --- a/src/Ryujinx.Headless.SDL2/WindowBase.cs +++ b/src/Ryujinx.Headless.SDL2/WindowBase.cs @@ -1,4 +1,3 @@ -using ARMeilleure.Translation; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Logging; @@ -276,7 +275,6 @@ namespace Ryujinx.Headless.SDL2 { Device.Gpu.SetGpuThread(); Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token); - Translator.IsReadyForTranslation.Set(); while (_isActive) { diff --git a/src/Ryujinx.Tests/Cpu/CpuTest.cs b/src/Ryujinx.Tests/Cpu/CpuTest.cs index 35158c0b..da0f03e6 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTest.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTest.cs @@ -61,7 +61,6 @@ namespace Ryujinx.Tests.Cpu _memory.Map(DataBaseAddress, Size, Size, MemoryMapFlags.Private); _context = CpuContext.CreateExecutionContext(); - Translator.IsReadyForTranslation.Set(); _cpuContext = new CpuContext(_memory, for64Bit: true); diff --git a/src/Ryujinx.Tests/Cpu/CpuTest32.cs b/src/Ryujinx.Tests/Cpu/CpuTest32.cs index f5eb94fa..6a690834 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTest32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTest32.cs @@ -56,7 +56,6 @@ namespace Ryujinx.Tests.Cpu _context = CpuContext.CreateExecutionContext(); _context.IsAarch32 = true; - Translator.IsReadyForTranslation.Set(); _cpuContext = new CpuContext(_memory, for64Bit: false); diff --git a/src/Ryujinx/Ui/MainWindow.cs b/src/Ryujinx/Ui/MainWindow.cs index 2a088f56..6cce034b 100644 --- a/src/Ryujinx/Ui/MainWindow.cs +++ b/src/Ryujinx/Ui/MainWindow.cs @@ -1,4 +1,3 @@ -using ARMeilleure.Translation; using Gtk; using LibHac.Common; using LibHac.Common.Keys; @@ -931,8 +930,6 @@ namespace Ryujinx.Ui _deviceExitStatus.Reset(); - Translator.IsReadyForTranslation.Reset(); - Thread windowThread = new(CreateGameWindow) { Name = "GUI.WindowThread", diff --git a/src/Ryujinx/Ui/RendererWidgetBase.cs b/src/Ryujinx/Ui/RendererWidgetBase.cs index 6ae122a0..7660f190 100644 --- a/src/Ryujinx/Ui/RendererWidgetBase.cs +++ b/src/Ryujinx/Ui/RendererWidgetBase.cs @@ -1,4 +1,3 @@ -using ARMeilleure.Translation; using Gdk; using Gtk; using Ryujinx.Common; @@ -450,7 +449,6 @@ namespace Ryujinx.Ui { Device.Gpu.SetGpuThread(); Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token); - Translator.IsReadyForTranslation.Set(); Renderer.Window.ChangeVSyncMode(Device.EnableDeviceVsync);