Compare commits

..

2 Commits

Author SHA1 Message Date
Ac_K
8cfec5de4b Avalonia: Cleanup UserEditor a bit (#3492)
This PR cleanup the UserEditor code a bit, 2 texts are added for "Name" and "User Id", because when you create a new profile, the textbox is empty without any hints. `axaml` files are autoformated too.
2022-07-28 14:16:23 -03:00
gdkchan
37b6e081da Fix DMA linear texture copy fast path (#3496)
* Fix DMA linear texture copy fast path

* Formatting
2022-07-28 13:46:12 -03:00
8 changed files with 143 additions and 94 deletions

View File

@@ -577,5 +577,7 @@
"UserProfileNoImageError": "Profile image must be set", "UserProfileNoImageError": "Profile image must be set",
"GameUpdateWindowHeading": "Updates Available for {0} [{1}]", "GameUpdateWindowHeading": "Updates Available for {0} [{1}]",
"SettingsTabHotkeysResScaleUpHotkey": "Increase resolution:", "SettingsTabHotkeysResScaleUpHotkey": "Increase resolution:",
"SettingsTabHotkeysResScaleDownHotkey": "Decrease resolution:" "SettingsTabHotkeysResScaleDownHotkey": "Decrease resolution:",
"UserProfilesName": "Name:",
"UserProfilesUserId" : "User Id:"
} }

View File

@@ -1,16 +1,17 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl
x:Class="Ryujinx.Ava.Ui.Controls.UserEditor"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Padding="0"
Margin="0"
xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
xmlns:models="clr-namespace:Ryujinx.Ava.Ui.Models" xmlns:models="clr-namespace:Ryujinx.Ava.Ui.Models"
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
x:Class="Ryujinx.Ava.Ui.Controls.UserEditor"> xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
Margin="0"
Padding="0"
mc:Ignorable="d">
<UserControl.Resources> <UserControl.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" /> <controls:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources> </UserControl.Resources>
@@ -23,33 +24,64 @@
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<StackPanel Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Left"> <StackPanel
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Orientation="Vertical">
<Image <Image
Name="ProfileImage"
Width="96"
Height="96"
Margin="0" Margin="0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Top" VerticalAlignment="Top"
Height="96" Width="96"
Name="ProfileImage"
Source="{Binding Image, Converter={StaticResource ByteImage}}" /> Source="{Binding Image, Converter={StaticResource ByteImage}}" />
<Button Margin="5" Content="{Locale:Locale UserProfilesChangeProfileImage}" <Button
Name="ChangePictureButton" Name="ChangePictureButton"
Margin="5"
HorizontalAlignment="Stretch"
Click="ChangePictureButton_Click" Click="ChangePictureButton_Click"
HorizontalAlignment="Stretch"/> Content="{Locale:Locale UserProfilesChangeProfileImage}" />
<Button Margin="5" Content="{Locale:Locale UserProfilesSetProfileImage}" <Button
Name="AddPictureButton" Name="AddPictureButton"
Margin="5"
HorizontalAlignment="Stretch"
Click="ChangePictureButton_Click" Click="ChangePictureButton_Click"
HorizontalAlignment="Stretch"/> Content="{Locale:Locale UserProfilesSetProfileImage}" />
</StackPanel> </StackPanel>
<StackPanel Grid.Row="0" Orientation="Vertical" HorizontalAlignment="Stretch" Grid.Column="1" Spacing="10" <StackPanel
Margin="5, 10"> Grid.Row="0"
<TextBox Name="NameBox" Width="300" Text="{Binding Name}" MaxLength="{Binding MaxProfileNameLength}" Grid.Column="1"
HorizontalAlignment="Stretch" /> Margin="5,10"
<TextBlock Text="{Binding UserId}" Name="IdLabel" /> HorizontalAlignment="Stretch"
Orientation="Vertical"
Spacing="10">
<TextBlock Text="{Locale:Locale UserProfilesName}" />
<TextBox
Name="NameBox"
Width="300"
HorizontalAlignment="Stretch"
MaxLength="{Binding MaxProfileNameLength}"
Text="{Binding Name}" />
<TextBlock Text="{Locale:Locale UserProfilesUserId}" />
<TextBlock Name="IdLabel" Text="{Binding UserId}" />
</StackPanel> </StackPanel>
<StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Orientation="Horizontal" Spacing="10" HorizontalAlignment="Right"> <StackPanel
<Button Content="{Locale:Locale Save}" Name="SaveButton" Click="SaveButton_Click"/> Grid.Row="1"
<Button HorizontalAlignment="Right" Content="{Locale:Locale Discard}" Grid.Column="0"
Name="CloseButton" Click="CloseButton_Click"/> Grid.ColumnSpan="2"
HorizontalAlignment="Right"
Orientation="Horizontal"
Spacing="10">
<Button
Name="SaveButton"
Click="SaveButton_Click"
Content="{Locale:Locale Save}" />
<Button
Name="CloseButton"
HorizontalAlignment="Right"
Click="CloseButton_Click"
Content="{Locale:Locale Discard}" />
</StackPanel> </StackPanel>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -63,7 +63,7 @@ namespace Ryujinx.Ava.Ui.Controls
_parent?.GoBack(); _parent?.GoBack();
} }
private void SaveButton_Click(object sender, RoutedEventArgs e) private async void SaveButton_Click(object sender, RoutedEventArgs e)
{ {
DataValidationErrors.ClearErrors(NameBox); DataValidationErrors.ClearErrors(NameBox);
bool isInvalid = false; bool isInvalid = false;
@@ -77,7 +77,7 @@ namespace Ryujinx.Ava.Ui.Controls
if (TempProfile.Image == null) if (TempProfile.Image == null)
{ {
ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["UserProfileNoImageError"], ""); await ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["UserProfileNoImageError"], "");
isInvalid = true; isInvalid = true;
} }

View File

@@ -1,28 +1,34 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl
x:Class="Ryujinx.Ava.Ui.Controls.UserSelector"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale" xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls" xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
x:Class="Ryujinx.Ava.Ui.Controls.UserSelector"> d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<UserControl.Resources> <UserControl.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" /> <controls:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources> </UserControl.Resources>
<Design.DataContext> <Design.DataContext>
<viewModels:UserProfileViewModel /> <viewModels:UserProfileViewModel />
</Design.DataContext> </Design.DataContext>
<Grid HorizontalAlignment="Stretch" <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
VerticalAlignment="Stretch">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition /> <RowDefinition />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ListBox HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="5" Items="{Binding Profiles}" <ListBox
Margin="5"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
DoubleTapped="ProfilesList_DoubleTapped" DoubleTapped="ProfilesList_DoubleTapped"
Items="{Binding Profiles}"
SelectionChanged="SelectingItemsControl_SelectionChanged"> SelectionChanged="SelectingItemsControl_SelectionChanged">
<ListBox.ItemsPanel> <ListBox.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
@@ -49,10 +55,11 @@
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Image <Image
Grid.Row="0" Grid.Row="0"
Width="96"
Height="96"
Margin="0" Margin="0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Top" VerticalAlignment="Top"
Height="96" Width="96"
Source="{Binding Image, Converter={StaticResource ByteImage}}" /> Source="{Binding Image, Converter={StaticResource ByteImage}}" />
<StackPanel <StackPanel
Grid.Row="1" Grid.Row="1"
@@ -68,23 +75,34 @@
</StackPanel> </StackPanel>
</Grid> </Grid>
</Border> </Border>
<Border HorizontalAlignment="Left" VerticalAlignment="Top" <Border
IsVisible="{Binding IsOpened}"
Background="LimeGreen"
Width="10" Width="10"
Height="10" Height="10"
Margin="5" Margin="5"
CornerRadius="5" /> HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="LimeGreen"
CornerRadius="5"
IsVisible="{Binding IsOpened}" />
</Grid> </Grid>
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>
</ListBox> </ListBox>
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="10,0" Spacing="10" HorizontalAlignment="Center"> <StackPanel
<Button Content="{Locale:Locale UserProfilesAddNewProfile}" Command="{Binding AddUser}" /> Grid.Row="1"
<Button IsEnabled="{Binding IsSelectedProfiledEditable}" Margin="10,0"
Content="{Locale:Locale UserProfilesEditProfile}" Command="{Binding EditUser}" /> HorizontalAlignment="Center"
<Button IsEnabled="{Binding IsSelectedProfileDeletable}" Orientation="Horizontal"
Content="{Locale:Locale UserProfilesDeleteSelectedProfile}" Command="{Binding DeleteUser}" /> Spacing="10">
<Button Command="{Binding AddUser}" Content="{Locale:Locale UserProfilesAddNewProfile}" />
<Button
Command="{Binding EditUser}"
Content="{Locale:Locale UserProfilesEditProfile}"
IsEnabled="{Binding IsSelectedProfiledEditable}" />
<Button
Command="{Binding DeleteUser}"
Content="{Locale:Locale UserProfilesDeleteSelectedProfile}"
IsEnabled="{Binding IsSelectedProfileDeletable}" />
</StackPanel> </StackPanel>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -21,7 +21,7 @@ namespace Ryujinx.Ava.Ui.Controls
AddHandler(Frame.NavigatedToEvent, (s, e) => AddHandler(Frame.NavigatedToEvent, (s, e) =>
{ {
NavigatedTo(e); NavigatedTo(e);
}, Avalonia.Interactivity.RoutingStrategies.Direct); }, RoutingStrategies.Direct);
} }
} }
@@ -29,12 +29,10 @@ namespace Ryujinx.Ava.Ui.Controls
{ {
if (Program.PreviewerDetached) if (Program.PreviewerDetached)
{ {
switch (arg.NavigationMode) if (arg.NavigationMode == NavigationMode.New)
{ {
case NavigationMode.New:
_parent = (NavigationDialogHost)arg.Parameter; _parent = (NavigationDialogHost)arg.Parameter;
ViewModel = _parent.ViewModel; ViewModel = _parent.ViewModel;
break;
} }
DataContext = ViewModel; DataContext = ViewModel;

View File

@@ -43,11 +43,9 @@ namespace Ryujinx.Ava.Ui.ViewModels
} }
} }
public bool IsHighlightedProfileEditable => public bool IsHighlightedProfileEditable => _highlightedProfile != null;
_highlightedProfile != null;
public bool IsHighlightedProfileDeletable => public bool IsHighlightedProfileDeletable => _highlightedProfile != null && _highlightedProfile.UserId != AccountManager.DefaultUserId;
_highlightedProfile != null && _highlightedProfile.UserId != AccountManager.DefaultUserId;
public UserProfile HighlightedProfile public UserProfile HighlightedProfile
{ {
@@ -62,16 +60,13 @@ namespace Ryujinx.Ava.Ui.ViewModels
} }
} }
public void Dispose() public void Dispose() { }
{
}
public void LoadProfiles() public void LoadProfiles()
{ {
Profiles.Clear(); Profiles.Clear();
var profiles = _owner.AccountManager.GetAllUsers() var profiles = _owner.AccountManager.GetAllUsers().OrderByDescending(x => x.AccountState == AccountState.Open);
.OrderByDescending(x => x.AccountState == AccountState.Open);
foreach (var profile in profiles) foreach (var profile in profiles)
{ {
@@ -94,6 +89,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
public void AddUser() public void AddUser()
{ {
UserProfile userProfile = null; UserProfile userProfile = null;
_owner.Navigate(typeof(UserEditor), (this._owner, userProfile, true)); _owner.Navigate(typeof(UserEditor), (this._owner, userProfile, true));
} }

View File

@@ -216,13 +216,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
{ {
var target = memoryManager.Physical.TextureCache.FindTexture( var target = memoryManager.Physical.TextureCache.FindTexture(
memoryManager, memoryManager,
dst,
dstGpuVa, dstGpuVa,
dstBpp, dstBpp,
dstStride, dstStride,
dst.Height,
xCount, xCount,
yCount, yCount,
dstLinear); dstLinear,
dst.MemoryLayout);
if (target != null) if (target != null)
{ {

View File

@@ -900,23 +900,25 @@ namespace Ryujinx.Graphics.Gpu.Image
/// Tries to find an existing texture matching the given buffer copy destination. If none is found, returns null. /// Tries to find an existing texture matching the given buffer copy destination. If none is found, returns null.
/// </summary> /// </summary>
/// <param name="memoryManager">GPU memory manager where the texture is mapped</param> /// <param name="memoryManager">GPU memory manager where the texture is mapped</param>
/// <param name="tex">The texture information</param>
/// <param name="gpuVa">GPU virtual address of the texture</param> /// <param name="gpuVa">GPU virtual address of the texture</param>
/// <param name="bpp">Bytes per pixel</param> /// <param name="bpp">Bytes per pixel</param>
/// <param name="stride">If <paramref name="linear"/> is true, should have the texture stride, otherwise ignored</param> /// <param name="stride">If <paramref name="linear"/> is true, should have the texture stride, otherwise ignored</param>
/// <param name="height">If <paramref name="linear"/> is false, should have the texture height, otherwise ignored</param>
/// <param name="xCount">Number of pixels to be copied per line</param> /// <param name="xCount">Number of pixels to be copied per line</param>
/// <param name="yCount">Number of lines to be copied</param> /// <param name="yCount">Number of lines to be copied</param>
/// <param name="linear">True if the texture has a linear layout, false otherwise</param> /// <param name="linear">True if the texture has a linear layout, false otherwise</param>
/// <param name="memoryLayout">If <paramref name="linear"/> is false, should have the memory layout, otherwise ignored</param>
/// <returns>A matching texture, or null if there is no match</returns> /// <returns>A matching texture, or null if there is no match</returns>
public Texture FindTexture( public Texture FindTexture(
MemoryManager memoryManager, MemoryManager memoryManager,
DmaTexture tex,
ulong gpuVa, ulong gpuVa,
int bpp, int bpp,
int stride, int stride,
int height,
int xCount, int xCount,
int yCount, int yCount,
bool linear) bool linear,
MemoryLayout memoryLayout)
{ {
ulong address = memoryManager.Translate(gpuVa); ulong address = memoryManager.Translate(gpuVa);
@@ -945,7 +947,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{ {
// Size is not available for linear textures. Use the stride and end of the copy region instead. // Size is not available for linear textures. Use the stride and end of the copy region instead.
match = texture.Info.IsLinear && texture.Info.Stride == stride && tex.RegionY + yCount <= texture.Info.Height; match = texture.Info.IsLinear && texture.Info.Stride == stride && yCount == texture.Info.Height;
} }
else else
{ {
@@ -953,10 +955,10 @@ namespace Ryujinx.Graphics.Gpu.Image
// Due to the way linear strided and block layouts work, widths can be multiplied by Bpp for comparison. // Due to the way linear strided and block layouts work, widths can be multiplied by Bpp for comparison.
// Note: tex.Width is the aligned texture size. Prefer param.XCount, as the destination should be a texture with that exact size. // Note: tex.Width is the aligned texture size. Prefer param.XCount, as the destination should be a texture with that exact size.
bool sizeMatch = xCount * bpp == texture.Info.Width * format.BytesPerPixel && tex.Height == texture.Info.Height; bool sizeMatch = xCount * bpp == texture.Info.Width * format.BytesPerPixel && height == texture.Info.Height;
bool formatMatch = !texture.Info.IsLinear && bool formatMatch = !texture.Info.IsLinear &&
texture.Info.GobBlocksInY == tex.MemoryLayout.UnpackGobBlocksInY() && texture.Info.GobBlocksInY == memoryLayout.UnpackGobBlocksInY() &&
texture.Info.GobBlocksInZ == tex.MemoryLayout.UnpackGobBlocksInZ(); texture.Info.GobBlocksInZ == memoryLayout.UnpackGobBlocksInZ();
match = sizeMatch && formatMatch; match = sizeMatch && formatMatch;
} }