diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs index 7f6a25b07..48c1a575c 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 2fd9ce00d..e434deb0a 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 a50852b05..aaf03ff79 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 af682e422..0b17af8b2 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 ff2185464..4de00978c 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 7e3c79f54..e545079b9 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 adab07641..1bfe43121 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 35158c0b4..da0f03e6b 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 f5eb94fa9..6a690834f 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 2a088f561..6cce034b6 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 6ae122a0a..7660f190e 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);