[GUI] Add the shader learning option and the precompile shaders action

This commit is contained in:
ParantezTech 2026-10-08 02:53:32 +03:00
parent 458e661806
commit a46c92ab1d
5 changed files with 140 additions and 5 deletions

View File

@ -78,6 +78,10 @@ public sealed class GuiSettings
public bool VSync { get; set; } = true;
public bool ShaderCache { get; set; } = true;
public bool ShaderLearn { get; set; }
public string HdrMode { get; set; } = "Auto";
public bool OverlayEnabled { get; set; } = true;

View File

@ -4,6 +4,7 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.VisualTree;
using SharpEmu.Libs.Gpu.ShaderCache;
using SharpEmu.Libs.VideoOut;
namespace SharpEmu.GUI;
@ -99,6 +100,8 @@ public partial class MainWindow
await CopyToClipboardAsync((GameList.SelectedItem as GameEntry)?.Path);
GameOptionsCopyTitleIdButton.Click += async (_, _) =>
await CopyToClipboardAsync((GameList.SelectedItem as GameEntry)?.TitleId);
GameOptionsClearShaderCacheButton.Click += (_, _) => ClearOpenGameShaderCache();
GameOptionsPrecompileShadersButton.Click += (_, _) => PrecompileOpenGameShaders();
GameOptionsRemoveButton.Click += (_, _) =>
{
CloseGameSettings();
@ -115,6 +118,8 @@ public partial class MainWindow
GameRefreshRateBox.SelectionChanged += (_, _) => PersistOpenGameSettings();
GameScalingModeBox.SelectionChanged += (_, _) => PersistOpenGameSettings();
GameVSyncToggle.IsCheckedChanged += (_, _) => PersistOpenGameSettings();
GameShaderCacheToggle.IsCheckedChanged += (_, _) => PersistOpenGameSettings();
GameShaderLearnToggle.IsCheckedChanged += (_, _) => PersistOpenGameSettings();
GameHdrModeBox.SelectionChanged += (_, _) => PersistOpenGameSettings();
GameOverlayEnabledToggle.IsCheckedChanged += (_, _) => PersistOpenGameSettings();
GameOverlayModeBox.SelectionChanged += (_, _) => PersistOpenGameSettings();
@ -127,6 +132,30 @@ public partial class MainWindow
SetGameOptionsSection(0, animateIndicator: false);
}
private void PrecompileOpenGameShaders()
{
if (GameList.SelectedItem is not GameEntry game || _isRunning)
{
return;
}
CloseGameSettings();
Launch(game.Path, game.Name, game.TitleId, precompileOnly: true);
}
private void ClearOpenGameShaderCache()
{
if (string.IsNullOrWhiteSpace(_gameSettingsTitleId))
{
return;
}
GameOptionsClearShaderCacheText.Text = Localization.Instance[
ShaderCacheSettings.TryClear(_gameSettingsTitleId)
? "Library.Context.ShaderCacheCleared"
: "Library.Context.ShaderCacheBusy"];
}
private void OpenSelectedGameSettings()
{
if (GameList.SelectedItem is not GameEntry game)
@ -144,9 +173,11 @@ public partial class MainWindow
_gameSettingsTitleId = game.TitleId;
GameOptionsOverlay.DataContext = game;
GameOptionsClearShaderCacheText.Text = Localization.Instance["Library.Context.ClearShaderCache"];
LoadGameSettings(game.TitleId);
SetGameOptionsSection(0, animateIndicator: false);
GameOptionsLaunchButton.IsEnabled = !_isRunning;
GameOptionsPrecompileShadersButton.IsEnabled = !_isRunning;
GameOptionsCopyTitleIdButton.IsEnabled =
!string.IsNullOrWhiteSpace(game.TitleId);
@ -217,6 +248,8 @@ public partial class MainWindow
effective.ScalingMode,
"Fit");
GameVSyncToggle.IsChecked = effective.VSync;
GameShaderCacheToggle.IsChecked = effective.ShaderCache;
GameShaderLearnToggle.IsChecked = effective.ShaderLearn;
GameOverlayEnabledToggle.IsChecked = effective.OverlayEnabled;
GameOverlayModeBox.SelectedItem = FindChoice(_overlayModeChoices, effective.OverlayMode, "TitleBar");
GameOverlayCornerBox.SelectedItem = FindChoice(_overlayCornerChoices, effective.OverlayCorner, "TopRight");
@ -283,6 +316,8 @@ public partial class MainWindow
RefreshRate = SelectedGameRefreshRate(),
ScalingMode = SelectedComboText(GameScalingModeBox, "Fit"),
VSync = GameVSyncToggle.IsChecked == true,
ShaderCache = GameShaderCacheToggle.IsChecked == true,
ShaderLearn = GameShaderLearnToggle.IsChecked == true,
HdrMode = SelectedComboText(GameHdrModeBox, "Auto"),
OverlayEnabled = GameOverlayEnabledToggle.IsChecked == true,
OverlayMode = SelectedComboText(GameOverlayModeBox, "TitleBar"),

View File

@ -755,6 +755,30 @@ SPDX-License-Identifier: GPL-2.0-or-later
VerticalAlignment="Center" />
</StackPanel>
</Button>
<Button x:Name="GameOptionsPrecompileShadersButton"
Classes="gameAction"
Margin="0,0,10,10">
<StackPanel Orientation="Horizontal"
Spacing="11">
<TextBlock Classes="materialSymbol"
Text="bolt" />
<TextBlock Text="{Binding [Library.Context.PrecompileShaders],
Source={x:Static local:Localization.Instance},
x:CompileBindings=False}"
VerticalAlignment="Center" />
</StackPanel>
</Button>
<Button x:Name="GameOptionsClearShaderCacheButton"
Classes="gameAction"
Margin="0,0,10,10">
<StackPanel Orientation="Horizontal"
Spacing="11">
<TextBlock Classes="materialSymbol"
Text="cleaning_services" />
<TextBlock x:Name="GameOptionsClearShaderCacheText"
VerticalAlignment="Center" />
</StackPanel>
</Button>
<Button x:Name="GameOptionsRemoveButton"
Classes="gameAction dangerAction"
Margin="0,0,10,10">
@ -925,6 +949,30 @@ SPDX-License-Identifier: GPL-2.0-or-later
Classes="optionToggle" />
</local:SettingRow>
<local:SettingRow x:Name="GameShaderCacheRow"
Classes="optionRow"
Label="{Binding [Options.ShaderCache.Label],
Source={x:Static local:Localization.Instance},
x:CompileBindings=False}"
Description="{Binding [Options.ShaderCache.Desc],
Source={x:Static local:Localization.Instance},
x:CompileBindings=False}">
<ToggleSwitch x:Name="GameShaderCacheToggle"
Classes="optionToggle" />
</local:SettingRow>
<local:SettingRow x:Name="GameShaderLearnRow"
Classes="optionRow"
Label="{Binding [Options.ShaderLearn.Label],
Source={x:Static local:Localization.Instance},
x:CompileBindings=False}"
Description="{Binding [Options.ShaderLearn.Desc],
Source={x:Static local:Localization.Instance},
x:CompileBindings=False}">
<ToggleSwitch x:Name="GameShaderLearnToggle"
Classes="optionToggle" />
</local:SettingRow>
<local:SettingRow x:Name="GameHdrModeRow"
Classes="optionRow"
Label="{Binding [Options.Hdr.Label],
@ -1540,6 +1588,21 @@ SPDX-License-Identifier: GPL-2.0-or-later
Classes="optionToggle"
IsChecked="True" />
</local:SettingRow>
<local:SettingRow x:Name="ShaderCacheRow"
Classes="optionRow"
Label="{Binding [Options.ShaderCache.Label], Source={x:Static local:Localization.Instance}}"
Description="{Binding [Options.ShaderCache.Desc], Source={x:Static local:Localization.Instance}}">
<ToggleSwitch x:Name="ShaderCacheToggle"
Classes="optionToggle"
IsChecked="True" />
</local:SettingRow>
<local:SettingRow x:Name="ShaderLearnRow"
Classes="optionRow"
Label="{Binding [Options.ShaderLearn.Label], Source={x:Static local:Localization.Instance}}"
Description="{Binding [Options.ShaderLearn.Desc], Source={x:Static local:Localization.Instance}}">
<ToggleSwitch x:Name="ShaderLearnToggle"
Classes="optionToggle" />
</local:SettingRow>
<local:SettingRow x:Name="HdrRow"
Classes="optionRow"
Label="{Binding [Options.Hdr.Label], Source={x:Static local:Localization.Instance}}"

View File

@ -215,7 +215,8 @@ public partial class MainWindow : Window
string ConsoleType,
string ConsoleLanguage,
EffectiveLaunchSettings Settings,
SharpEmuRuntimeOptions RuntimeOptions);
SharpEmuRuntimeOptions RuntimeOptions,
bool PrecompileOnly = false);
public MainWindow()
{
@ -359,6 +360,8 @@ public partial class MainWindow : Window
RefreshRateBox.SelectionChanged += (_, _) => OnHostRefreshRateChanged();
ScalingModeBox.SelectionChanged += (_, _) => _settings.ScalingMode = SelectedComboText(ScalingModeBox, "Fit");
VSyncToggle.IsCheckedChanged += (_, _) => _settings.VSync = VSyncToggle.IsChecked == true;
ShaderCacheToggle.IsCheckedChanged += (_, _) => _settings.ShaderCache = ShaderCacheToggle.IsChecked == true;
ShaderLearnToggle.IsCheckedChanged += (_, _) => _settings.ShaderLearn = ShaderLearnToggle.IsChecked == true;
HdrModeBox.SelectionChanged += (_, _) => _settings.HdrMode = SelectedComboText(HdrModeBox, "Auto");
OverlayEnabledToggle.IsCheckedChanged += (_, _) => _settings.OverlayEnabled = OverlayEnabledToggle.IsChecked == true;
OverlayModeBox.SelectionChanged += (_, _) => _settings.OverlayMode = SelectedComboText(OverlayModeBox, "TitleBar");
@ -1448,6 +1451,8 @@ public partial class MainWindow : Window
LoadHostDisplayOptions();
ScalingModeBox.SelectedIndex = ChoiceIndex(_settings.ScalingMode, "Fit", "Cover", "Stretch", "Integer");
VSyncToggle.IsChecked = _settings.VSync;
ShaderCacheToggle.IsChecked = _settings.ShaderCache;
ShaderLearnToggle.IsChecked = _settings.ShaderLearn;
HdrModeBox.SelectedIndex = ChoiceIndex(_settings.HdrMode, "Auto", "On", "Off");
OverlayEnabledToggle.IsChecked = _settings.OverlayEnabled;
OverlayModeBox.SelectedIndex = ChoiceIndex(_settings.OverlayMode, "Full", "Minimal", "TitleBar");
@ -2803,7 +2808,8 @@ public partial class MainWindow : Window
string ebootPath,
string displayName,
string? titleId = null,
IReadOnlyList<string>? oneShotCustomEnvironment = null)
IReadOnlyList<string>? oneShotCustomEnvironment = null,
bool precompileOnly = false)
{
if (_isRunning)
{
@ -2936,7 +2942,8 @@ public partial class MainWindow : Window
_settings.ConsoleType,
_settings.ConsoleLanguage,
effective,
runtimeOptions);
runtimeOptions,
precompileOnly);
StartPendingSession();
}
@ -3119,10 +3126,16 @@ public partial class MainWindow : Window
arguments.Add($"--refresh-rate={launch.Settings.RefreshRate}");
arguments.Add($"--scaling={launch.Settings.ScalingMode.ToLowerInvariant()}");
arguments.Add($"--vsync={(launch.Settings.VSync ? "on" : "off")}");
arguments.Add($"--shader-cache={(launch.Settings.ShaderCache ? "on" : "off")}");
arguments.Add($"--shader-learn={(launch.Settings.ShaderLearn ? "on" : "off")}");
arguments.Add($"--hdr={launch.Settings.HdrMode.ToLowerInvariant()}");
arguments.Add($"--overlay={(launch.Settings.OverlayEnabled ? "on" : "off")}");
arguments.Add($"--overlay-mode={launch.Settings.OverlayMode.ToLowerInvariant()}");
arguments.Add($"--overlay-corner={launch.Settings.OverlayCorner.ToLowerInvariant()}");
if (launch.PrecompileOnly)
{
arguments.Add("--precompile-only");
}
arguments.Add(launch.EbootPath);
return arguments;

View File

@ -34,6 +34,10 @@ public sealed class PerGameSettings
public bool? VSync { get; set; }
public bool? ShaderCache { get; set; }
public bool? ShaderLearn { get; set; }
public string? HdrMode { get; set; }
public bool? OverlayEnabled { get; set; }
@ -56,6 +60,8 @@ public sealed class PerGameSettings
RefreshRate is null &&
ScalingMode is null &&
VSync is null &&
ShaderCache is null &&
ShaderLearn is null &&
HdrMode is null &&
OverlayEnabled is null &&
OverlayCorner is null &&
@ -165,6 +171,16 @@ public sealed class PerGameSettings
VSync = null;
}
if (ShaderCache == global.ShaderCache)
{
ShaderCache = null;
}
if (ShaderLearn == global.ShaderLearn)
{
ShaderLearn = null;
}
if (string.Equals(HdrMode, global.HdrMode, StringComparison.OrdinalIgnoreCase))
{
HdrMode = null;
@ -280,7 +296,9 @@ public sealed record EffectiveLaunchSettings(
bool OverlayEnabled,
string OverlayCorner,
string OverlayMode,
IReadOnlyList<string> EnvironmentToggles)
IReadOnlyList<string> EnvironmentToggles,
bool ShaderCache = true,
bool ShaderLearn = false)
{
public static EffectiveLaunchSettings Resolve(GuiSettings global, PerGameSettings? perGame) => new(
perGame?.LogLevel ?? global.LogLevel,
@ -297,5 +315,7 @@ public sealed record EffectiveLaunchSettings(
perGame?.OverlayEnabled ?? global.OverlayEnabled,
perGame?.OverlayCorner ?? global.OverlayCorner,
perGame?.OverlayMode ?? global.OverlayMode,
perGame?.EnvironmentToggles ?? global.EnvironmentToggles);
perGame?.EnvironmentToggles ?? global.EnvironmentToggles,
perGame?.ShaderCache ?? global.ShaderCache,
perGame?.ShaderLearn ?? global.ShaderLearn);
}