Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
79becc4b78 | |||
223172ac0b | |||
8c9633d72f |
@ -17,6 +17,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
private const ulong BufferAlignmentSize = 0x1000;
|
||||
private const ulong BufferAlignmentMask = BufferAlignmentSize - 1;
|
||||
|
||||
private const ulong MaxDynamicGrowthSize = 0x100000;
|
||||
|
||||
private readonly GpuContext _context;
|
||||
private readonly PhysicalMemory _physicalMemory;
|
||||
|
||||
@ -166,10 +168,35 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
// Otherwise, we must delete the overlapping buffers and create a bigger buffer
|
||||
// that fits all the data we need. We also need to copy the contents from the
|
||||
// old buffer(s) to the new buffer.
|
||||
|
||||
ulong endAddress = address + size;
|
||||
|
||||
if (_bufferOverlaps[0].Address > address || _bufferOverlaps[0].EndAddress < endAddress)
|
||||
{
|
||||
// Check if the following conditions are met:
|
||||
// - We have a single overlap.
|
||||
// - The overlap starts at or before the requested range. That is, the overlap happens at the end.
|
||||
// - The size delta between the new, merged buffer and the old one is of at most 2 pages.
|
||||
// In this case, we attempt to extend the buffer further than the requested range,
|
||||
// this can potentially avoid future resizes if the application keeps using overlapping
|
||||
// sequential memory.
|
||||
// Allowing for 2 pages (rather than just one) is necessary to catch cases where the
|
||||
// range crosses a page, and after alignment, ends having a size of 2 pages.
|
||||
if (overlapsCount == 1 &&
|
||||
address >= _bufferOverlaps[0].Address &&
|
||||
endAddress - _bufferOverlaps[0].EndAddress <= BufferAlignmentSize * 2)
|
||||
{
|
||||
// Try to grow the buffer by 1.5x of its current size.
|
||||
// This improves performance in the cases where the buffer is resized often by small amounts.
|
||||
ulong existingSize = _bufferOverlaps[0].Size;
|
||||
ulong growthSize = (existingSize + Math.Min(existingSize >> 1, MaxDynamicGrowthSize)) & ~BufferAlignmentMask;
|
||||
|
||||
size = Math.Max(size, growthSize);
|
||||
endAddress = address + size;
|
||||
|
||||
overlapsCount = _buffers.FindOverlapsNonOverlapping(address, size, ref _bufferOverlaps);
|
||||
}
|
||||
|
||||
for (int index = 0; index < overlapsCount; index++)
|
||||
{
|
||||
Buffer buffer = _bufferOverlaps[index];
|
||||
@ -183,7 +210,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
}
|
||||
}
|
||||
|
||||
Buffer newBuffer = new Buffer(_context, _physicalMemory, address, endAddress - address, _bufferOverlaps.Take(overlapsCount));
|
||||
ulong newSize = endAddress - address;
|
||||
|
||||
Buffer newBuffer = new Buffer(_context, _physicalMemory, address, newSize, _bufferOverlaps.Take(overlapsCount));
|
||||
|
||||
lock (_buffers)
|
||||
{
|
||||
@ -202,7 +231,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
buffer.DisposeData();
|
||||
}
|
||||
|
||||
newBuffer.SynchronizeMemory(address, endAddress - address);
|
||||
newBuffer.SynchronizeMemory(address, newSize);
|
||||
|
||||
// Existing buffers were modified, we need to rebind everything.
|
||||
NotifyBuffersModified?.Invoke();
|
||||
|
@ -328,6 +328,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
public void SetAllInputUserAttributes()
|
||||
{
|
||||
UsedInputAttributes |= Constants.AllAttributesMask;
|
||||
ThisInputAttributesComponents |= ~UInt128.Zero >> (128 - Constants.MaxAttributes * 4);
|
||||
}
|
||||
|
||||
public void SetAllOutputUserAttributes()
|
||||
|
@ -10,6 +10,12 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
private ulong _v0;
|
||||
private ulong _v1;
|
||||
|
||||
public UInt128(ulong low, ulong high)
|
||||
{
|
||||
_v0 = low;
|
||||
_v1 = high;
|
||||
}
|
||||
|
||||
public int TrailingZeroCount()
|
||||
{
|
||||
int count = BitOperations.TrailingZeroCount(_v0);
|
||||
@ -25,25 +31,57 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
{
|
||||
if (x >= 64)
|
||||
{
|
||||
return new UInt128() { _v0 = 0, _v1 = 1UL << (x - 64 ) };
|
||||
return new UInt128(0, 1UL << (x - 64));
|
||||
}
|
||||
|
||||
return new UInt128() { _v0 = 1UL << x, _v1 = 0 };
|
||||
return new UInt128(1UL << x, 0);
|
||||
}
|
||||
|
||||
public static UInt128 operator ~(UInt128 x)
|
||||
{
|
||||
return new UInt128() { _v0 = ~x._v0, _v1 = ~x._v1 };
|
||||
return new UInt128(~x._v0, ~x._v1);
|
||||
}
|
||||
|
||||
public static UInt128 operator &(UInt128 x, UInt128 y)
|
||||
{
|
||||
return new UInt128() { _v0 = x._v0 & y._v0, _v1 = x._v1 & y._v1 };
|
||||
return new UInt128(x._v0 & y._v0, x._v1 & y._v1);
|
||||
}
|
||||
|
||||
public static UInt128 operator |(UInt128 x, UInt128 y)
|
||||
{
|
||||
return new UInt128() { _v0 = x._v0 | y._v0, _v1 = x._v1 | y._v1 };
|
||||
return new UInt128(x._v0 | y._v0, x._v1 | y._v1);
|
||||
}
|
||||
|
||||
public static UInt128 operator <<(UInt128 x, int shift)
|
||||
{
|
||||
if (shift == 0)
|
||||
{
|
||||
return new UInt128(x._v0, x._v1);
|
||||
}
|
||||
else if (shift >= 64)
|
||||
{
|
||||
return new UInt128(0, x._v0 << (shift - 64));
|
||||
}
|
||||
|
||||
ulong shiftOut = x._v0 >> (64 - shift);
|
||||
|
||||
return new UInt128(x._v0 << shift, (x._v1 << shift) | shiftOut);
|
||||
}
|
||||
|
||||
public static UInt128 operator >>(UInt128 x, int shift)
|
||||
{
|
||||
if (shift == 0)
|
||||
{
|
||||
return new UInt128(x._v0, x._v1);
|
||||
}
|
||||
else if (shift >= 64)
|
||||
{
|
||||
return new UInt128(x._v1 >> (shift - 64), 0);
|
||||
}
|
||||
|
||||
ulong shiftOut = x._v1 & ((1UL << shift) - 1);
|
||||
|
||||
return new UInt128((x._v0 >> shift) | (shiftOut << (64 - shift)), x._v1 >> shift);
|
||||
}
|
||||
|
||||
public static bool operator ==(UInt128 x, UInt128 y)
|
||||
|
@ -14,7 +14,7 @@ namespace Ryujinx.Configuration
|
||||
/// <summary>
|
||||
/// The current version of the file format
|
||||
/// </summary>
|
||||
public const int CurrentVersion = 36;
|
||||
public const int CurrentVersion = 37;
|
||||
|
||||
/// <summary>
|
||||
/// Version of the configuration file format
|
||||
@ -236,6 +236,11 @@ namespace Ryujinx.Configuration
|
||||
/// </summary>
|
||||
public bool StartFullscreen { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Show console window
|
||||
/// </summary>
|
||||
public bool ShowConsole { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable or disable keyboard support (Independent from controllers binding)
|
||||
/// </summary>
|
||||
|
@ -6,6 +6,7 @@ using Ryujinx.Common.Configuration.Hid.Keyboard;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Configuration.System;
|
||||
using Ryujinx.Configuration.Ui;
|
||||
using Ryujinx.Ui.Helper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -88,6 +89,11 @@ namespace Ryujinx.Configuration
|
||||
/// </summary>
|
||||
public ReactiveObject<bool> StartFullscreen { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Hide / Show Console Window
|
||||
/// </summary>
|
||||
public ReactiveObject<bool> ShowConsole { get; private set; }
|
||||
|
||||
public UiSection()
|
||||
{
|
||||
GuiColumns = new Columns();
|
||||
@ -96,6 +102,8 @@ namespace Ryujinx.Configuration
|
||||
EnableCustomTheme = new ReactiveObject<bool>();
|
||||
CustomThemePath = new ReactiveObject<string>();
|
||||
StartFullscreen = new ReactiveObject<bool>();
|
||||
ShowConsole = new ReactiveObject<bool>();
|
||||
ShowConsole.Event += static (s, e) => { ConsoleHelper.SetConsoleWindowState(e.NewValue); };
|
||||
}
|
||||
}
|
||||
|
||||
@ -508,6 +516,7 @@ namespace Ryujinx.Configuration
|
||||
EnableCustomTheme = Ui.EnableCustomTheme,
|
||||
CustomThemePath = Ui.CustomThemePath,
|
||||
StartFullscreen = Ui.StartFullscreen,
|
||||
ShowConsole = Ui.ShowConsole,
|
||||
EnableKeyboard = Hid.EnableKeyboard,
|
||||
EnableMouse = Hid.EnableMouse,
|
||||
Hotkeys = Hid.Hotkeys,
|
||||
@ -574,6 +583,7 @@ namespace Ryujinx.Configuration
|
||||
Ui.EnableCustomTheme.Value = false;
|
||||
Ui.CustomThemePath.Value = "";
|
||||
Ui.StartFullscreen.Value = false;
|
||||
Ui.ShowConsole.Value = true;
|
||||
Hid.EnableKeyboard.Value = false;
|
||||
Hid.EnableMouse.Value = false;
|
||||
Hid.Hotkeys.Value = new KeyboardHotkeys
|
||||
@ -995,7 +1005,7 @@ namespace Ryujinx.Configuration
|
||||
controllerConfig.RangeRight = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
configurationFileUpdated = true;
|
||||
}
|
||||
|
||||
@ -1007,7 +1017,16 @@ namespace Ryujinx.Configuration
|
||||
|
||||
configurationFileUpdated = true;
|
||||
}
|
||||
|
||||
|
||||
if (configurationFileFormat.Version < 37)
|
||||
{
|
||||
Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 37.");
|
||||
|
||||
configurationFileFormat.ShowConsole = true;
|
||||
|
||||
configurationFileUpdated = true;
|
||||
}
|
||||
|
||||
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
||||
Graphics.BackendThreading.Value = configurationFileFormat.BackendThreading;
|
||||
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
||||
@ -1061,6 +1080,7 @@ namespace Ryujinx.Configuration
|
||||
Ui.EnableCustomTheme.Value = configurationFileFormat.EnableCustomTheme;
|
||||
Ui.CustomThemePath.Value = configurationFileFormat.CustomThemePath;
|
||||
Ui.StartFullscreen.Value = configurationFileFormat.StartFullscreen;
|
||||
Ui.ShowConsole.Value = configurationFileFormat.ShowConsole;
|
||||
Hid.EnableKeyboard.Value = configurationFileFormat.EnableKeyboard;
|
||||
Hid.EnableMouse.Value = configurationFileFormat.EnableMouse;
|
||||
Hid.Hotkeys.Value = configurationFileFormat.Hotkeys;
|
||||
|
49
Ryujinx/Ui/Helper/ConsoleHelper.cs
Normal file
49
Ryujinx/Ui/Helper/ConsoleHelper.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using Ryujinx.Common.Logging;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Ryujinx.Ui.Helper
|
||||
{
|
||||
public static class ConsoleHelper
|
||||
{
|
||||
public static bool SetConsoleWindowStateSupported => OperatingSystem.IsWindows();
|
||||
|
||||
public static void SetConsoleWindowState(bool show)
|
||||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
SetConsoleWindowStateWindows(show);
|
||||
}
|
||||
else if (show == false)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Application, "OS doesn't support hiding console window");
|
||||
}
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
private static void SetConsoleWindowStateWindows(bool show)
|
||||
{
|
||||
const int SW_HIDE = 0;
|
||||
const int SW_SHOW = 5;
|
||||
|
||||
IntPtr hWnd = GetConsoleWindow();
|
||||
|
||||
if (hWnd == IntPtr.Zero)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Application, "Attempted to show/hide console window but console window does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
[DllImport("kernel32")]
|
||||
static extern IntPtr GetConsoleWindow();
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
[DllImport("user32")]
|
||||
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
}
|
||||
}
|
@ -107,6 +107,7 @@ namespace Ryujinx.Ui
|
||||
[GUI] MenuItem _hideUi;
|
||||
[GUI] MenuItem _fullScreen;
|
||||
[GUI] CheckMenuItem _startFullScreen;
|
||||
[GUI] CheckMenuItem _showConsole;
|
||||
[GUI] CheckMenuItem _favToggle;
|
||||
[GUI] MenuItem _firmwareInstallDirectory;
|
||||
[GUI] MenuItem _firmwareInstallFile;
|
||||
@ -213,6 +214,9 @@ namespace Ryujinx.Ui
|
||||
_startFullScreen.Active = true;
|
||||
}
|
||||
|
||||
_showConsole.Active = ConfigurationState.Instance.Ui.ShowConsole.Value;
|
||||
_showConsole.Visible = ConsoleHelper.SetConsoleWindowStateSupported;
|
||||
|
||||
_actionMenu.Sensitive = false;
|
||||
_pauseEmulation.Sensitive = false;
|
||||
_resumeEmulation.Sensitive = false;
|
||||
@ -1535,6 +1539,13 @@ namespace Ryujinx.Ui
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
private void ShowConsole_Toggled(object sender, EventArgs args)
|
||||
{
|
||||
ConfigurationState.Instance.Ui.ShowConsole.Value = _showConsole.Active;
|
||||
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
private void OptionMenu_StateChanged(object o, StateChangedArgs args)
|
||||
{
|
||||
_manageUserProfiles.Sensitive = _emulationContext == null;
|
||||
|
@ -142,6 +142,15 @@
|
||||
<signal name="toggled" handler="StartFullScreen_Toggled" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="_showConsole">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Show Log Console</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="toggled" handler="ShowConsole_Toggled" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
<property name="visible">True</property>
|
||||
|
Reference in New Issue
Block a user