From c19c8bbadea027e4f31a0739fac0f2a27fbe6dbf Mon Sep 17 00:00:00 2001 From: Theun de Bruijn Date: Thu, 6 Jul 2023 20:10:15 +1000 Subject: [PATCH 1/7] Headless: Add support for fullscreen option (#5339) * Headless: Added support for fullscreen option * Headless: cleanup of fullscreen support * Headless: fullscreen support : implemented proposed changes * Headless: fullscreen support: cleanup * Headless: fullscreen support: fix for OpenGL scaling * Headless: fullscreen support: cleanup * Headless: fullscreen support: cleanup * Headless: fullscreen support: add. macOS fullscreen fix * Headless: fullscreen support: cleanup * Headless: fullscreen support: cleanup * Headless: fullscreen support: cleanup --- .../OpenGL/OpenGLWindow.cs | 18 ++++++++++++++++-- src/Ryujinx.Headless.SDL2/Options.cs | 3 +++ src/Ryujinx.Headless.SDL2/Program.cs | 5 +++++ src/Ryujinx.Headless.SDL2/WindowBase.cs | 19 ++++++++++++++----- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs b/src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs index 199f723e9..355dcf6c7 100644 --- a/src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs +++ b/src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs @@ -151,8 +151,22 @@ namespace Ryujinx.Headless.SDL2.OpenGL GL.Clear(ClearBufferMask.ColorBufferBit); SwapBuffers(); - Renderer?.Window.SetSize(DefaultWidth, DefaultHeight); - MouseDriver.SetClientSize(DefaultWidth, DefaultHeight); + if (IsFullscreen) + { + // NOTE: grabbing the main display's dimensions directly as OpenGL doesn't scale along like the VulkanWindow. + // we might have to amend this if people run this on a non-primary display set to a different resolution. + SDL_Rect displayBounds; + SDL_GetDisplayBounds(0, out displayBounds); + + Renderer?.Window.SetSize(displayBounds.w, displayBounds.h); + MouseDriver.SetClientSize(displayBounds.w, displayBounds.h); + } + + else + { + Renderer?.Window.SetSize(DefaultWidth, DefaultHeight); + MouseDriver.SetClientSize(DefaultWidth, DefaultHeight); + } } protected override void InitializeRenderer() { } diff --git a/src/Ryujinx.Headless.SDL2/Options.cs b/src/Ryujinx.Headless.SDL2/Options.cs index 86a6c63c4..e44cedec9 100644 --- a/src/Ryujinx.Headless.SDL2/Options.cs +++ b/src/Ryujinx.Headless.SDL2/Options.cs @@ -14,6 +14,9 @@ namespace Ryujinx.Headless.SDL2 [Option("profile", Required = false, HelpText = "Set the user profile to launch the game with.")] public string UserProfile { get; set; } + [Option("fullscreen", Required = false, HelpText = "Launch the game in fullscreen mode.")] + public bool IsFullscreen { get; set; } + // Input [Option("input-profile-1", Required = false, HelpText = "Set the input profile in use for Player 1.")] diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs index 39eae14a8..98cc5abf4 100644 --- a/src/Ryujinx.Headless.SDL2/Program.cs +++ b/src/Ryujinx.Headless.SDL2/Program.cs @@ -64,6 +64,9 @@ namespace Ryujinx.Headless.SDL2 { Version = ReleaseInformation.GetVersion(); + // Make process DPI aware for proper window sizing on high-res screens. + ForceDpiAware.Windows(); + Console.Title = $"Ryujinx Console {Version} (Headless SDL2)"; if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux()) @@ -592,6 +595,8 @@ namespace Ryujinx.Headless.SDL2 _window = window; + _window.IsFullscreen = options.IsFullscreen; + _emulationContext = InitializeEmulationContext(window, renderer, options); SystemVersion firmwareVersion = _contentManager.GetCurrentFirmwareVersion(); diff --git a/src/Ryujinx.Headless.SDL2/WindowBase.cs b/src/Ryujinx.Headless.SDL2/WindowBase.cs index 2fcd00f86..c542a4e61 100644 --- a/src/Ryujinx.Headless.SDL2/WindowBase.cs +++ b/src/Ryujinx.Headless.SDL2/WindowBase.cs @@ -55,6 +55,7 @@ namespace Ryujinx.Headless.SDL2 public IHostUiTheme HostUiTheme { get; } public int Width { get; private set; } public int Height { get; private set; } + public bool IsFullscreen { get; set; } protected SDL2MouseDriver MouseDriver; private readonly InputManager _inputManager; @@ -158,7 +159,9 @@ namespace Ryujinx.Headless.SDL2 string titleIdSection = string.IsNullOrWhiteSpace(activeProcess.ProgramIdText) ? string.Empty : $" ({activeProcess.ProgramIdText.ToUpper()})"; string titleArchSection = activeProcess.Is64Bit ? " (64-bit)" : " (32-bit)"; - WindowHandle = SDL_CreateWindow($"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, DefaultWidth, DefaultHeight, DefaultFlags | GetWindowFlags()); + SDL_WindowFlags fullscreenFlag = IsFullscreen ? SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP : 0; + + WindowHandle = SDL_CreateWindow($"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, DefaultWidth, DefaultHeight, DefaultFlags | fullscreenFlag | GetWindowFlags()); if (WindowHandle == IntPtr.Zero) { @@ -185,10 +188,16 @@ namespace Ryujinx.Headless.SDL2 switch (evnt.window.windowEvent) { case SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED: - Width = evnt.window.data1; - Height = evnt.window.data2; - Renderer?.Window.SetSize(Width, Height); - MouseDriver.SetClientSize(Width, Height); + // Unlike on Windows, this event fires on macOS when triggering fullscreen mode. + // And promptly crashes the process because `Renderer?.window.SetSize` is undefined. + // As we don't need this to fire in either case we can test for isFullscreen. + if (!IsFullscreen) + { + Width = evnt.window.data1; + Height = evnt.window.data2; + Renderer?.Window.SetSize(Width, Height); + MouseDriver.SetClientSize(Width, Height); + } break; case SDL_WindowEventID.SDL_WINDOWEVENT_CLOSE: From 2b5abac809dacb351ec69e322732d45ea01a4d65 Mon Sep 17 00:00:00 2001 From: SuperSamus <40663462+SuperSamus@users.noreply.github.com> Date: Thu, 6 Jul 2023 17:11:26 +0200 Subject: [PATCH 2/7] sdl: set `SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS` to 0 (#5433) Nintendo controllers notoriously have the A/B and X/Y buttons swapped, compared to the standard. In order to combat this, when setting the default controller layout, Ryujinx checks whether the controller name contains "Nintendo", and swaps the mapping accordingly. However, the reason the mapping is inverted in the first place is because SDL has `SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS` set to 1 by default. By setting it to 0, the mapping will be based on the buttons' position instead. So, by doing it (and removing the `isNintendoStyle` variable), we get the following advantages: - The mapping will be the same on all controllers, removing the need to adjust custom mappings depending on what controller is used - Users who already set `SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS` to 0 globally for other games/applications (like me) won't have a wrong default mapping - Checking whether the controller name contains "Nintendo" is ugly Disadvantages: - Breaks the controller configuration for existing users who are using a Nintendo controller --- .../UI/ViewModels/ControllerInputViewModel.cs | 10 ++++------ src/Ryujinx.Headless.SDL2/Program.cs | 10 ++++------ src/Ryujinx.SDL2.Common/SDL2Driver.cs | 1 + src/Ryujinx/Ui/Windows/ControllerWindow.cs | 10 ++++------ 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs index fda58504e..8b5dbcef0 100644 --- a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs +++ b/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs @@ -597,8 +597,6 @@ namespace Ryujinx.Ava.UI.ViewModels } else if (activeDevice.Type == DeviceType.Controller) { - bool isNintendoStyle = Devices.ToList().Find(x => x.Id == activeDevice.Id).Name.Contains("Nintendo"); - string id = activeDevice.Id.Split(" ")[0]; config = new StandardControllerInputConfig @@ -633,10 +631,10 @@ namespace Ryujinx.Ava.UI.ViewModels }, RightJoycon = new RightJoyconCommonConfig { - ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B, - ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A, - ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y, - ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X, + ButtonA = ConfigGamepadInputId.B, + ButtonB = ConfigGamepadInputId.A, + ButtonX = ConfigGamepadInputId.Y, + ButtonY = ConfigGamepadInputId.X, ButtonPlus = ConfigGamepadInputId.Plus, ButtonR = ConfigGamepadInputId.RightShoulder, ButtonZr = ConfigGamepadInputId.RightTrigger, diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs index 98cc5abf4..ffcac9ed5 100644 --- a/src/Ryujinx.Headless.SDL2/Program.cs +++ b/src/Ryujinx.Headless.SDL2/Program.cs @@ -195,8 +195,6 @@ namespace Ryujinx.Headless.SDL2 } else { - bool isNintendoStyle = gamepadName.Contains("Nintendo"); - config = new StandardControllerInputConfig { Version = InputConfig.CurrentVersion, @@ -232,10 +230,10 @@ namespace Ryujinx.Headless.SDL2 RightJoycon = new RightJoyconCommonConfig { - ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B, - ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A, - ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y, - ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X, + ButtonA = ConfigGamepadInputId.B, + ButtonB = ConfigGamepadInputId.A, + ButtonX = ConfigGamepadInputId.Y, + ButtonY = ConfigGamepadInputId.X, ButtonPlus = ConfigGamepadInputId.Plus, ButtonR = ConfigGamepadInputId.RightShoulder, ButtonZr = ConfigGamepadInputId.RightTrigger, diff --git a/src/Ryujinx.SDL2.Common/SDL2Driver.cs b/src/Ryujinx.SDL2.Common/SDL2Driver.cs index 2642b26fa..3411fa041 100644 --- a/src/Ryujinx.SDL2.Common/SDL2Driver.cs +++ b/src/Ryujinx.SDL2.Common/SDL2Driver.cs @@ -60,6 +60,7 @@ namespace Ryujinx.SDL2.Common SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED, "0"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1"); + SDL_SetHint(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0"); SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1"); diff --git a/src/Ryujinx/Ui/Windows/ControllerWindow.cs b/src/Ryujinx/Ui/Windows/ControllerWindow.cs index ebf22ab60..2993e1f23 100644 --- a/src/Ryujinx/Ui/Windows/ControllerWindow.cs +++ b/src/Ryujinx/Ui/Windows/ControllerWindow.cs @@ -1035,8 +1035,6 @@ namespace Ryujinx.Ui.Windows } else if (_inputDevice.ActiveId.StartsWith("controller")) { - bool isNintendoStyle = _inputDevice.ActiveText.Contains("Nintendo"); - config = new StandardControllerInputConfig { Version = InputConfig.CurrentVersion, @@ -1072,10 +1070,10 @@ namespace Ryujinx.Ui.Windows RightJoycon = new RightJoyconCommonConfig { - ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B, - ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A, - ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y, - ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X, + ButtonA = ConfigGamepadInputId.B, + ButtonB = ConfigGamepadInputId.A, + ButtonX = ConfigGamepadInputId.Y, + ButtonY = ConfigGamepadInputId.X, ButtonPlus = ConfigGamepadInputId.Plus, ButtonR = ConfigGamepadInputId.RightShoulder, ButtonZr = ConfigGamepadInputId.RightTrigger, From 8a363b5df2387bd254a3dd48bfd3c9884ff74dab Mon Sep 17 00:00:00 2001 From: Mary Date: Thu, 6 Jul 2023 18:08:14 +0200 Subject: [PATCH 3/7] Revert "sdl: set `SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS` to 0 (#5433)" (#5439) This reverts commit 2b5abac809dacb351ec69e322732d45ea01a4d65. --- .../UI/ViewModels/ControllerInputViewModel.cs | 10 ++++++---- src/Ryujinx.Headless.SDL2/Program.cs | 10 ++++++---- src/Ryujinx.SDL2.Common/SDL2Driver.cs | 1 - src/Ryujinx/Ui/Windows/ControllerWindow.cs | 10 ++++++---- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs index 8b5dbcef0..fda58504e 100644 --- a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs +++ b/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs @@ -597,6 +597,8 @@ namespace Ryujinx.Ava.UI.ViewModels } else if (activeDevice.Type == DeviceType.Controller) { + bool isNintendoStyle = Devices.ToList().Find(x => x.Id == activeDevice.Id).Name.Contains("Nintendo"); + string id = activeDevice.Id.Split(" ")[0]; config = new StandardControllerInputConfig @@ -631,10 +633,10 @@ namespace Ryujinx.Ava.UI.ViewModels }, RightJoycon = new RightJoyconCommonConfig { - ButtonA = ConfigGamepadInputId.B, - ButtonB = ConfigGamepadInputId.A, - ButtonX = ConfigGamepadInputId.Y, - ButtonY = ConfigGamepadInputId.X, + ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B, + ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A, + ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y, + ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X, ButtonPlus = ConfigGamepadInputId.Plus, ButtonR = ConfigGamepadInputId.RightShoulder, ButtonZr = ConfigGamepadInputId.RightTrigger, diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs index ffcac9ed5..98cc5abf4 100644 --- a/src/Ryujinx.Headless.SDL2/Program.cs +++ b/src/Ryujinx.Headless.SDL2/Program.cs @@ -195,6 +195,8 @@ namespace Ryujinx.Headless.SDL2 } else { + bool isNintendoStyle = gamepadName.Contains("Nintendo"); + config = new StandardControllerInputConfig { Version = InputConfig.CurrentVersion, @@ -230,10 +232,10 @@ namespace Ryujinx.Headless.SDL2 RightJoycon = new RightJoyconCommonConfig { - ButtonA = ConfigGamepadInputId.B, - ButtonB = ConfigGamepadInputId.A, - ButtonX = ConfigGamepadInputId.Y, - ButtonY = ConfigGamepadInputId.X, + ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B, + ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A, + ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y, + ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X, ButtonPlus = ConfigGamepadInputId.Plus, ButtonR = ConfigGamepadInputId.RightShoulder, ButtonZr = ConfigGamepadInputId.RightTrigger, diff --git a/src/Ryujinx.SDL2.Common/SDL2Driver.cs b/src/Ryujinx.SDL2.Common/SDL2Driver.cs index 3411fa041..2642b26fa 100644 --- a/src/Ryujinx.SDL2.Common/SDL2Driver.cs +++ b/src/Ryujinx.SDL2.Common/SDL2Driver.cs @@ -60,7 +60,6 @@ namespace Ryujinx.SDL2.Common SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED, "0"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1"); - SDL_SetHint(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0"); SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1"); diff --git a/src/Ryujinx/Ui/Windows/ControllerWindow.cs b/src/Ryujinx/Ui/Windows/ControllerWindow.cs index 2993e1f23..ebf22ab60 100644 --- a/src/Ryujinx/Ui/Windows/ControllerWindow.cs +++ b/src/Ryujinx/Ui/Windows/ControllerWindow.cs @@ -1035,6 +1035,8 @@ namespace Ryujinx.Ui.Windows } else if (_inputDevice.ActiveId.StartsWith("controller")) { + bool isNintendoStyle = _inputDevice.ActiveText.Contains("Nintendo"); + config = new StandardControllerInputConfig { Version = InputConfig.CurrentVersion, @@ -1070,10 +1072,10 @@ namespace Ryujinx.Ui.Windows RightJoycon = new RightJoyconCommonConfig { - ButtonA = ConfigGamepadInputId.B, - ButtonB = ConfigGamepadInputId.A, - ButtonX = ConfigGamepadInputId.Y, - ButtonY = ConfigGamepadInputId.X, + ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B, + ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A, + ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y, + ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X, ButtonPlus = ConfigGamepadInputId.Plus, ButtonR = ConfigGamepadInputId.RightShoulder, ButtonZr = ConfigGamepadInputId.RightTrigger, From 21d5593446ad145a94c05f0bbd2037a64452156e Mon Sep 17 00:00:00 2001 From: sunshineinabox Date: Wed, 5 Jul 2023 23:30:49 -0700 Subject: [PATCH 4/7] Implement a method to get Physical Core Count and resolve pending TODO --- src/ARMeilleure/Translation/Translator.cs | 7 ++- src/Ryujinx.Common/SystemInfo/SystemInfo.cs | 49 +++++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs index dc18038ba..f6911920b 100644 --- a/src/ARMeilleure/Translation/Translator.cs +++ b/src/ARMeilleure/Translation/Translator.cs @@ -10,6 +10,7 @@ using ARMeilleure.State; using ARMeilleure.Translation.Cache; using ARMeilleure.Translation.PTC; using Ryujinx.Common; +using Ryujinx.Common.SystemInfo; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -103,6 +104,7 @@ namespace ARMeilleure.Translation public void Execute(State.ExecutionContext context, ulong address) { + int physicalCoreCount = SystemInfo.GetPhysicalCoreCount(); if (Interlocked.Increment(ref _threadCount) == 1) { IsReadyForTranslation.WaitOne(); @@ -122,10 +124,7 @@ namespace ARMeilleure.Translation // etc). All threads are normal priority except from the last, which just fills as much of the last core // as the os lets it with a low priority. If we only have one rejit thread, it should be normal priority // as highCq code is performance critical. - // - // TODO: Use physical cores rather than logical. This only really makes sense for processors with - // hyperthreading. Requires OS specific code. - int unboundedThreadCount = Math.Max(1, (Environment.ProcessorCount - 6) / 3); + int unboundedThreadCount = Math.Max(1, (physicalCoreCount - 6) / 3); int threadCount = Math.Min(4, unboundedThreadCount); Thread[] backgroundTranslationThreads = new Thread[threadCount]; diff --git a/src/Ryujinx.Common/SystemInfo/SystemInfo.cs b/src/Ryujinx.Common/SystemInfo/SystemInfo.cs index 55ec0127c..c4e941aa4 100644 --- a/src/Ryujinx.Common/SystemInfo/SystemInfo.cs +++ b/src/Ryujinx.Common/SystemInfo/SystemInfo.cs @@ -1,5 +1,8 @@ using Ryujinx.Common.Logging; using System; +using System.Diagnostics; +using System.IO; +using System.Linq; using System.Runtime.InteropServices; using System.Runtime.Intrinsics.X86; using System.Text; @@ -74,5 +77,51 @@ namespace Ryujinx.Common.SystemInfo return string.IsNullOrEmpty(name) ? null : name; } + + public static int GetPhysicalCoreCount() + { + int coreCount = Environment.ProcessorCount; + + try + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + coreCount = 0; + foreach (var item in new System.Management.ManagementObjectSearcher("Select NumberOfCores from Win32_Processor").Get()) + { + coreCount += int.Parse(item["NumberOfCores"].ToString()); + } + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + coreCount = File.ReadLines("/proc/cpuinfo") + .Count(line => line.Contains("cpu cores")); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "sysctl", + Arguments = "-n hw.physicalcpu", + UseShellExecute = false, + RedirectStandardOutput = true, + CreateNoWindow = true + } + }; + + process.Start(); + coreCount = int.Parse(process.StandardOutput.ReadToEnd()); + process.WaitForExit(); + } + } + catch (Exception ex) + { + Console.WriteLine("An error occurred while trying to get the physical core count: " + ex.Message); + } + + return coreCount; + } } } From 00fee4715e4b932a30b00d21401e7fc673c2046e Mon Sep 17 00:00:00 2001 From: sunshineinabox Date: Thu, 6 Jul 2023 00:53:40 -0700 Subject: [PATCH 5/7] Thanks to Benedani on Discord this should be correct way to get physical cores on linux now --- src/Ryujinx.Common/SystemInfo/SystemInfo.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Ryujinx.Common/SystemInfo/SystemInfo.cs b/src/Ryujinx.Common/SystemInfo/SystemInfo.cs index c4e941aa4..878422513 100644 --- a/src/Ryujinx.Common/SystemInfo/SystemInfo.cs +++ b/src/Ryujinx.Common/SystemInfo/SystemInfo.cs @@ -94,8 +94,18 @@ namespace Ryujinx.Common.SystemInfo } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { - coreCount = File.ReadLines("/proc/cpuinfo") - .Count(line => line.Contains("cpu cores")); + string cpuCoresLine = File.ReadLines("/proc/cpuinfo") + .FirstOrDefault(line => line.Contains("cpu cores")); + + if (cpuCoresLine != null) + { + string[] parts = cpuCoresLine.Split(':'); + if (parts.Length == 2 && int.TryParse(parts[1].Trim(), out int cores)) + { + coreCount = cores; + Console.WriteLine("Number of physical cores: " + coreCount); + } + } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { From 44ede2c6b81e60d81dcf46c3f0bc39ff7006f0a7 Mon Sep 17 00:00:00 2001 From: sunshineinabox Date: Thu, 6 Jul 2023 20:24:25 -0700 Subject: [PATCH 6/7] Address Feedback --- src/ARMeilleure/Translation/Translator.cs | 1 + src/Ryujinx.Common/SystemInfo/SystemInfo.cs | 12 ++++-------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs index f6911920b..d3bf6c4f9 100644 --- a/src/ARMeilleure/Translation/Translator.cs +++ b/src/ARMeilleure/Translation/Translator.cs @@ -105,6 +105,7 @@ namespace ARMeilleure.Translation public void Execute(State.ExecutionContext context, ulong address) { int physicalCoreCount = SystemInfo.GetPhysicalCoreCount(); + if (Interlocked.Increment(ref _threadCount) == 1) { IsReadyForTranslation.WaitOne(); diff --git a/src/Ryujinx.Common/SystemInfo/SystemInfo.cs b/src/Ryujinx.Common/SystemInfo/SystemInfo.cs index 878422513..f17b921b4 100644 --- a/src/Ryujinx.Common/SystemInfo/SystemInfo.cs +++ b/src/Ryujinx.Common/SystemInfo/SystemInfo.cs @@ -94,17 +94,11 @@ namespace Ryujinx.Common.SystemInfo } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { - string cpuCoresLine = File.ReadLines("/proc/cpuinfo") - .FirstOrDefault(line => line.Contains("cpu cores")); + string cpuCoresLine = File.ReadLines("/proc/cpuinfo").FirstOrDefault(line => line.Contains("cpu cores")); if (cpuCoresLine != null) { string[] parts = cpuCoresLine.Split(':'); - if (parts.Length == 2 && int.TryParse(parts[1].Trim(), out int cores)) - { - coreCount = cores; - Console.WriteLine("Number of physical cores: " + coreCount); - } } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -122,13 +116,15 @@ namespace Ryujinx.Common.SystemInfo }; process.Start(); + coreCount = int.Parse(process.StandardOutput.ReadToEnd()); + process.WaitForExit(); } } catch (Exception ex) { - Console.WriteLine("An error occurred while trying to get the physical core count: " + ex.Message); + Logger.Error?.Print(LogClass.Application,"An error occurred while trying to get the physical core count: {ex.Message}"); } return coreCount; From 1500432c6815110e94c35cb042b5d3b53385b068 Mon Sep 17 00:00:00 2001 From: sunshineinabox Date: Thu, 6 Jul 2023 20:35:36 -0700 Subject: [PATCH 7/7] Error in previous commit "cpu cores" line was being read but not parsed. Correctly use Ryujinx logger now to actually show message. --- src/Ryujinx.Common/SystemInfo/SystemInfo.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Ryujinx.Common/SystemInfo/SystemInfo.cs b/src/Ryujinx.Common/SystemInfo/SystemInfo.cs index f17b921b4..4b92b0c9c 100644 --- a/src/Ryujinx.Common/SystemInfo/SystemInfo.cs +++ b/src/Ryujinx.Common/SystemInfo/SystemInfo.cs @@ -99,6 +99,7 @@ namespace Ryujinx.Common.SystemInfo if (cpuCoresLine != null) { string[] parts = cpuCoresLine.Split(':'); + coreCount = int.Parse(parts[1]); } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -124,7 +125,7 @@ namespace Ryujinx.Common.SystemInfo } catch (Exception ex) { - Logger.Error?.Print(LogClass.Application,"An error occurred while trying to get the physical core count: {ex.Message}"); + Logger.Error?.Print(LogClass.Application,$"An error occurred while trying to get the physical core count: {ex.Message}"); } return coreCount;