From 863edae3283d92ba94a4b68c673ad3bff458b6dd Mon Sep 17 00:00:00 2001 From: Mary Date: Tue, 17 Nov 2020 22:40:19 +0100 Subject: [PATCH] shader cache: Fix Linux boot issues (#1709) * shader cache: Fix Linux boot issues This rollback the init logic back to previous state, and replicate the way PTC handle initialization. * shader cache: set default state of ready for translation event to false * Fix cpu unit tests --- ARMeilleure/Translation/Translator.cs | 5 +++ Ryujinx.Graphics.Gpu/GpuContext.cs | 15 +------ Ryujinx.HLE/HOS/ApplicationLoader.cs | 4 -- Ryujinx.Tests/Cpu/CpuTest.cs | 2 + Ryujinx.Tests/Cpu/CpuTest32.cs | 2 + Ryujinx/Ui/GLRenderer.cs | 22 +++++++++- Ryujinx/Ui/MainWindow.cs | 58 ++++++++------------------- 7 files changed, 48 insertions(+), 60 deletions(-) diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs index 0c9d6842f..80f7b9625 100644 --- a/ARMeilleure/Translation/Translator.cs +++ b/ARMeilleure/Translation/Translator.cs @@ -31,6 +31,9 @@ namespace ARMeilleure.Translation private volatile int _threadCount; + // FIXME: Remove this once the init logic of the emulator will be redone + public static ManualResetEvent IsReadyForTranslation = new ManualResetEvent(false); + public Translator(IJitMemoryAllocator allocator, IMemoryManager memory) { _memory = memory; @@ -83,6 +86,8 @@ namespace ARMeilleure.Translation { if (Interlocked.Increment(ref _threadCount) == 1) { + IsReadyForTranslation.WaitOne(); + if (Ptc.State == PtcState.Enabled) { Ptc.MakeAndSaveTranslations(_funcs, _memory, _jumpTable); diff --git a/Ryujinx.Graphics.Gpu/GpuContext.cs b/Ryujinx.Graphics.Gpu/GpuContext.cs index b62b5f3a4..6834afb42 100644 --- a/Ryujinx.Graphics.Gpu/GpuContext.cs +++ b/Ryujinx.Graphics.Gpu/GpuContext.cs @@ -1,4 +1,3 @@ -using Ryujinx.Common.Configuration; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine; using Ryujinx.Graphics.Gpu.Engine.GPFifo; @@ -19,11 +18,6 @@ namespace Ryujinx.Graphics.Gpu /// public ManualResetEvent HostInitalized { get; } - /// - /// Event signaled when the gpu context is ready to be used. - /// - public ManualResetEvent ReadyEvent { get; } - /// /// Host renderer. /// @@ -93,20 +87,16 @@ namespace Ryujinx.Graphics.Gpu _caps = new Lazy(Renderer.GetCapabilities); HostInitalized = new ManualResetEvent(false); - ReadyEvent = new ManualResetEvent(false); } /// - /// Initialize the GPU emulation context. + /// Initialize the GPU shader cache. /// - /// The log level required. - public void Initialize(GraphicsDebugLevel logLevel) + public void InitializeShaderCache() { HostInitalized.WaitOne(); - Renderer.Initialize(logLevel); Methods.ShaderCache.Initialize(); - ReadyEvent.Set(); } /// @@ -142,7 +132,6 @@ namespace Ryujinx.Graphics.Gpu Renderer.Dispose(); GPFifo.Dispose(); HostInitalized.Dispose(); - ReadyEvent.Dispose(); } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/ApplicationLoader.cs b/Ryujinx.HLE/HOS/ApplicationLoader.cs index 96fb3a1f8..9bf9a7bf8 100644 --- a/Ryujinx.HLE/HOS/ApplicationLoader.cs +++ b/Ryujinx.HLE/HOS/ApplicationLoader.cs @@ -503,8 +503,6 @@ namespace Ryujinx.HLE.HOS Ptc.Initialize(TitleIdText, DisplayVersion, _device.System.EnablePtc && !modified); - _device.Gpu.ReadyEvent.WaitOne(); - ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, executables: programs); } @@ -602,9 +600,7 @@ namespace Ryujinx.HLE.HOS // Explicitly null titleid to disable the shader cache Graphics.Gpu.GraphicsConfig.TitleId = null; - _device.Gpu.HostInitalized.Set(); - _device.Gpu.ReadyEvent.WaitOne(); ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, executables: executable); } diff --git a/Ryujinx.Tests/Cpu/CpuTest.cs b/Ryujinx.Tests/Cpu/CpuTest.cs index e0778e058..24a60cb52 100644 --- a/Ryujinx.Tests/Cpu/CpuTest.cs +++ b/Ryujinx.Tests/Cpu/CpuTest.cs @@ -1,4 +1,5 @@ using ARMeilleure.State; +using ARMeilleure.Translation; using NUnit.Framework; using Ryujinx.Cpu; using Ryujinx.Memory; @@ -54,6 +55,7 @@ namespace Ryujinx.Tests.Cpu _memory.Map(CodeBaseAddress, 0, Size * 2); _context = CpuContext.CreateExecutionContext(); + Translator.IsReadyForTranslation.Set(); _cpuContext = new CpuContext(_memory); diff --git a/Ryujinx.Tests/Cpu/CpuTest32.cs b/Ryujinx.Tests/Cpu/CpuTest32.cs index ca9668407..910ae2e07 100644 --- a/Ryujinx.Tests/Cpu/CpuTest32.cs +++ b/Ryujinx.Tests/Cpu/CpuTest32.cs @@ -1,4 +1,5 @@ using ARMeilleure.State; +using ARMeilleure.Translation; using NUnit.Framework; using Ryujinx.Cpu; using Ryujinx.Memory; @@ -52,6 +53,7 @@ namespace Ryujinx.Tests.Cpu _context = CpuContext.CreateExecutionContext(); _context.IsAarch32 = true; + Translator.IsReadyForTranslation.Set(); _cpuContext = new CpuContext(_memory); diff --git a/Ryujinx/Ui/GLRenderer.cs b/Ryujinx/Ui/GLRenderer.cs index 0e5ef8f23..60012519b 100644 --- a/Ryujinx/Ui/GLRenderer.cs +++ b/Ryujinx/Ui/GLRenderer.cs @@ -1,4 +1,5 @@ -using ARMeilleure.Translation.PTC; +using ARMeilleure.Translation; +using ARMeilleure.Translation.PTC; using Gdk; using OpenTK; using OpenTK.Graphics; @@ -199,6 +200,20 @@ namespace Ryujinx.Ui Gtk.Application.Invoke(delegate { parent.Present(); + + + string titleNameSection = string.IsNullOrWhiteSpace(_device.Application.TitleName) ? string.Empty + : $" - {_device.Application.TitleName}"; + + string titleVersionSection = string.IsNullOrWhiteSpace(_device.Application.DisplayVersion) ? string.Empty + : $" v{_device.Application.DisplayVersion}"; + + string titleIdSection = string.IsNullOrWhiteSpace(_device.Application.TitleIdText) ? string.Empty + : $" ({_device.Application.TitleIdText.ToUpper()})"; + + string titleArchSection = _device.Application.TitleIs64Bit ? " (64-bit)" : " (32-bit)"; + + parent.Title = $"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}"; }); Thread renderLoopThread = new Thread(Render) @@ -314,13 +329,16 @@ namespace Ryujinx.Ui parent.Present(); GraphicsContext.MakeCurrent(WindowInfo); - _device.Gpu.Initialize(_glLogLevel); + _device.Gpu.Renderer.Initialize(_glLogLevel); // Make sure the first frame is not transparent. GL.ClearColor(OpenTK.Color.Black); GL.Clear(ClearBufferMask.ColorBufferBit); SwapBuffers(); + _device.Gpu.InitializeShaderCache(); + Translator.IsReadyForTranslation.Set(); + while (IsActive) { if (IsStopped) diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs index 25407ff31..b1ab2bdff 100644 --- a/Ryujinx/Ui/MainWindow.cs +++ b/Ryujinx/Ui/MainWindow.cs @@ -1,3 +1,4 @@ +using ARMeilleure.Translation; using ARMeilleure.Translation.PTC; using Gtk; using LibHac.Common; @@ -39,7 +40,6 @@ namespace Ryujinx.Ui public static GlRenderer GlWidget => _glWidget; private static AutoResetEvent _deviceExitStatus = new AutoResetEvent(false); - private static AutoResetEvent _widgetInitEvent = new AutoResetEvent(false); private static ListStore _tableStore; @@ -435,30 +435,6 @@ namespace Ryujinx.Ui } } - _widgetInitEvent.Reset(); - -#if MACOS_BUILD - CreateGameWindow(device); -#else - Thread windowThread = new Thread(() => - { - CreateGameWindow(device); - }) - { - Name = "GUI.WindowThread" - }; - - windowThread.Start(); -#endif - - _widgetInitEvent.WaitOne(); - - // Make sure the widget get initialized by forcing an update of GTK - while (Application.EventsPending()) - { - Application.RunIteration(); - } - Logger.Notice.Print(LogClass.Application, $"Using Firmware Version: {firmwareVersion?.VersionString}"); if (Directory.Exists(path)) @@ -519,24 +495,26 @@ namespace Ryujinx.Ui return; } - string titleNameSection = string.IsNullOrWhiteSpace(device.Application.TitleName) ? string.Empty - : $" - {device.Application.TitleName}"; - - string titleVersionSection = string.IsNullOrWhiteSpace(device.Application.DisplayVersion) ? string.Empty - : $" v{device.Application.DisplayVersion}"; - - string titleIdSection = string.IsNullOrWhiteSpace(device.Application.TitleIdText) ? string.Empty - : $" ({device.Application.TitleIdText.ToUpper()})"; - - string titleArchSection = device.Application.TitleIs64Bit ? " (64-bit)" : " (32-bit)"; - - Title = $"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}"; - _emulationContext = device; _gamePath = path; _deviceExitStatus.Reset(); + Translator.IsReadyForTranslation.Reset(); +#if MACOS_BUILD + CreateGameWindow(device); +#else + Thread windowThread = new Thread(() => + { + CreateGameWindow(device); + }) + { + Name = "GUI.WindowThread" + }; + + windowThread.Start(); +#endif + _gameLoaded = true; _stopEmulation.Sensitive = true; @@ -559,7 +537,7 @@ namespace Ryujinx.Ui _windowsMultimediaTimerResolution = new WindowsMultimediaTimerResolution(1); } - _glWidget = new GlRenderer(device, ConfigurationState.Instance.Logger.GraphicsDebugLevel); + _glWidget = new GlRenderer(_emulationContext, ConfigurationState.Instance.Logger.GraphicsDebugLevel); Application.Invoke(delegate { @@ -576,8 +554,6 @@ namespace Ryujinx.Ui } }); - _widgetInitEvent.Set(); - _glWidget.WaitEvent.WaitOne(); _glWidget.Start();