Compare commits

..

10 Commits

Author SHA1 Message Date
Isaac Marovitz
121296834a Ava GUI: Several UI Fixes (#3991)
* Fix accessability violations in ListView

* Use accent colour for favourite star

* Hide progress bar when its done

* App Data Formating

- Added space before storage unit
- Changed so minutes have 0 decimals, and hours and days have 1

* Fix theming

* Fix mismatched corner radius

* Fix acceability violations in GridView

* More consistency between Grid and List View

* Fix margin

* Let whitespace defocus controls
2022-12-05 22:04:18 +00:00
gdkchan
bbb24d8c7e Restrict shader storage buffer search when match fails (#4011)
* Restrict storage buffer search when match fails

* Shader cache version bump
2022-12-05 19:11:32 +00:00
Andrey Sukharev
4da44e09cb Make structs readonly when applicable (#4002)
* Make all structs readonly when applicable. It should reduce amount of needless defensive copies

* Make structs with trivial boilerplate equality code record structs

* Remove unnecessary readonly modifiers from TextureCreateInfo

* Make BitMap structs readonly too
2022-12-05 14:47:39 +01:00
Mary-nyan
ae13f0ab4d misc: Fix obsolete warnings in Ryujinx.Graphics.Vulkan (#4020)
Was caused by some merges after the Silk.NET update
2022-12-05 12:57:11 +00:00
dependabot[bot]
a2a35f1be6 nuget: bump Microsoft.NET.Test.Sdk from 16.8.0 to 17.4.0 (#3900)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 16.8.0 to 17.4.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v16.8.0...v17.4.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-05 08:17:40 +01:00
Shane Slattery
aedfadaaf7 Add InfoType.MesosphereCurrentProcess (#3792)
* Add InfoType.MesosphereCurrentProcess

* Make outHandle inlined

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
2022-12-04 19:46:02 +00:00
Ethan Page
5c0fb0cec3 ui: Disallow checking for updates while emulation active (#3886)
* Disallow updating while game is running

* Reflected change on Avalonia

* Git has gone wonky

* Fix accidental indent
2022-12-04 20:17:11 +01:00
gdkchan
17a1cab5d2 Allow SNorm buffer texture formats on Vulkan (#3957)
* Allow SNorm buffer texture formats on Vulkan

* Shader cache version bump
2022-12-04 15:36:03 -03:00
gdkchan
73aed239c3 Implement non-MS to MS copies with draws (#3958)
* Implement non-MS to MS copies with draws, simplify MS to non-MS copies and supports any host sample count

* Remove unused program
2022-12-04 15:07:11 -03:00
riperiperi
9ac66336a2 GPU: Use lazy checks for specialization state (#4004)
* GPU: Use lazy checks for specialization state

This PR adds a new class, the SpecializationStateUpdater, that allows elements of specialization state to be updated individually, and signal the state is checked when it changes between draws, instead of building and checking it on every draw. This also avoids building spec state when

Most state updates have been moved behind the shader state update, so that their specialization state updates make it in before shaders are fetched.

Downside: Fields in GpuChannelGraphicsState are no longer readonly. To counteract copies that might be caused this I pass it as `ref` when possible, though maybe `in` would be better? Not really sure about the quirks of `in` and the difference probably won't show on a benchmark.

The result is around 2 extra FPS on SMO in the usual spot. Not much right now, but it will remove costs when we're doing more expensive specialization checks, such as fragment output type specialization for macos. It may also help more on other games with more draws.

* Address Feedback

* Oops
2022-12-04 18:41:17 +01:00
196 changed files with 1336 additions and 1061 deletions

View File

@@ -89,6 +89,7 @@ csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences # Modifier preferences
csharp_prefer_static_local_function = true:suggestion csharp_prefer_static_local_function = true:suggestion
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
csharp_style_prefer_readonly_struct = true
# Code-block preferences # Code-block preferences
csharp_prefer_braces = true:silent csharp_prefer_braces = true:silent

View File

@@ -1,6 +1,6 @@
namespace ARMeilleure.CodeGen.RegisterAllocators namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
struct AllocationResult readonly struct AllocationResult
{ {
public int IntUsedRegisters { get; } public int IntUsedRegisters { get; }
public int VecUsedRegisters { get; } public int VecUsedRegisters { get; }

View File

@@ -11,7 +11,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
private class ParallelCopy private class ParallelCopy
{ {
private struct Copy private readonly struct Copy
{ {
public Register Dest { get; } public Register Dest { get; }
public Register Source { get; } public Register Source { get; }

View File

@@ -11,7 +11,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
class HybridAllocator : IRegisterAllocator class HybridAllocator : IRegisterAllocator
{ {
private struct BlockInfo private readonly struct BlockInfo
{ {
public bool HasCall { get; } public bool HasCall { get; }

View File

@@ -3,7 +3,7 @@ using System;
namespace ARMeilleure.CodeGen.RegisterAllocators namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
struct RegisterMasks readonly struct RegisterMasks
{ {
public int IntAvailableRegisters { get; } public int IntAvailableRegisters { get; }
public int VecAvailableRegisters { get; } public int VecAvailableRegisters { get; }

View File

@@ -1,6 +1,6 @@
namespace ARMeilleure.CodeGen.X86 namespace ARMeilleure.CodeGen.X86
{ {
struct IntrinsicInfo readonly struct IntrinsicInfo
{ {
public X86Instruction Inst { get; } public X86Instruction Inst { get; }
public IntrinsicType Type { get; } public IntrinsicType Type { get; }

View File

@@ -2,7 +2,7 @@ using ARMeilleure.Instructions;
namespace ARMeilleure.Decoders namespace ARMeilleure.Decoders
{ {
struct InstDescriptor readonly struct InstDescriptor
{ {
public static InstDescriptor Undefined => new InstDescriptor(InstName.Und, InstEmit.Und); public static InstDescriptor Undefined => new InstDescriptor(InstName.Und, InstEmit.Und);

View File

@@ -11,7 +11,7 @@ namespace ARMeilleure.Decoders
private const int FastLookupSize = 0x1000; private const int FastLookupSize = 0x1000;
private struct InstInfo private readonly struct InstInfo
{ {
public int Mask { get; } public int Mask { get; }
public int Value { get; } public int Value { get; }

View File

@@ -6,7 +6,7 @@ namespace ARMeilleure.Diagnostics
{ {
static class Symbols static class Symbols
{ {
private struct RangedSymbol private readonly struct RangedSymbol
{ {
public readonly ulong Start; public readonly ulong Start;
public readonly ulong End; public readonly ulong End;

View File

@@ -3,7 +3,7 @@ using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
namespace ARMeilleure.IntermediateRepresentation namespace ARMeilleure.IntermediateRepresentation
{ {
struct PhiOperation readonly struct PhiOperation
{ {
private readonly Operation _operation; private readonly Operation _operation;

View File

@@ -2,7 +2,7 @@ using System;
namespace ARMeilleure.IntermediateRepresentation namespace ARMeilleure.IntermediateRepresentation
{ {
struct Register : IEquatable<Register> readonly struct Register : IEquatable<Register>
{ {
public int Index { get; } public int Index { get; }

View File

@@ -4,7 +4,7 @@ using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.Translation.Cache namespace ARMeilleure.Translation.Cache
{ {
struct CacheEntry : IComparable<CacheEntry> readonly struct CacheEntry : IComparable<CacheEntry>
{ {
public int Offset { get; } public int Offset { get; }
public int Size { get; } public int Size { get; }

View File

@@ -6,7 +6,7 @@ namespace ARMeilleure.Translation.Cache
{ {
class CacheMemoryAllocator class CacheMemoryAllocator
{ {
private struct MemoryBlock : IComparable<MemoryBlock> private readonly struct MemoryBlock : IComparable<MemoryBlock>
{ {
public int Offset { get; } public int Offset { get; }
public int Size { get; } public int Size { get; }

View File

@@ -2,7 +2,7 @@ using ARMeilleure.IntermediateRepresentation;
namespace ARMeilleure.Translation namespace ARMeilleure.Translation
{ {
struct CompilerContext readonly struct CompilerContext
{ {
public ControlFlowGraph Cfg { get; } public ControlFlowGraph Cfg { get; }

View File

@@ -14,7 +14,7 @@ namespace ARMeilleure.Translation
private const int RegsCount = 32; private const int RegsCount = 32;
private const int RegsMask = RegsCount - 1; private const int RegsMask = RegsCount - 1;
private struct RegisterMask : IEquatable<RegisterMask> private readonly struct RegisterMask : IEquatable<RegisterMask>
{ {
public long IntMask => Mask.GetElement(0); public long IntMask => Mask.GetElement(0);
public long VecMask => Mask.GetElement(1); public long VecMask => Mask.GetElement(1);

View File

@@ -293,7 +293,7 @@ namespace ARMeilleure.Translation
} }
} }
private struct Range private readonly struct Range
{ {
public ulong Start { get; } public ulong Start { get; }
public ulong End { get; } public ulong End { get; }

View File

@@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
namespace SoundIOSharp namespace SoundIOSharp
{ {
public struct SoundIOChannelLayout public readonly struct SoundIOChannelLayout
{ {
public static int BuiltInCount public static int BuiltInCount
{ {

View File

@@ -1,6 +1,6 @@
namespace SoundIOSharp namespace SoundIOSharp
{ {
public struct SoundIOSampleRateRange public readonly struct SoundIOSampleRateRange
{ {
internal SoundIOSampleRateRange(int min, int max) internal SoundIOSampleRateRange(int min, int max)
{ {

View File

@@ -58,5 +58,7 @@
<Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color> <Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
<Color x:Key="ThemeForegroundColor">#FFFFFFFF</Color> <Color x:Key="ThemeForegroundColor">#FFFFFFFF</Color>
<Color x:Key="MenuFlyoutPresenterBorderColor">#3D3D3D</Color> <Color x:Key="MenuFlyoutPresenterBorderColor">#3D3D3D</Color>
<Color x:Key="AppListBackgroundColor">#0FFFFFFF</Color>
<Color x:Key="AppListHoverBackgroundColor">#1EFFFFFF</Color>
</Styles.Resources> </Styles.Resources>
</Styles> </Styles>

View File

@@ -50,5 +50,7 @@
<Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color> <Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
<Color x:Key="ThemeForegroundColor">#FF000000</Color> <Color x:Key="ThemeForegroundColor">#FF000000</Color>
<Color x:Key="MenuFlyoutPresenterBorderColor">#C1C1C1</Color> <Color x:Key="MenuFlyoutPresenterBorderColor">#C1C1C1</Color>
<Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
<Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
</Styles.Resources> </Styles.Resources>
</Styles> </Styles>

View File

@@ -11,7 +11,8 @@
Height="340" Height="340"
CanResize="False" CanResize="False"
SizeToContent="Height" SizeToContent="Height"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<Grid <Grid
Margin="20" Margin="20"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"

View File

@@ -6,7 +6,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows" xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
Width="400" Width="400"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<Grid <Grid
Margin="20" Margin="20"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"

View File

@@ -10,7 +10,8 @@
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
d:DesignHeight="450" d:DesignHeight="450"
d:DesignWidth="800" d:DesignWidth="800"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<UserControl.Resources> <UserControl.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" /> <controls:BitmapArrayValueConverter x:Key="ByteImage" />
<MenuFlyout x:Key="GameContextMenu" Opened="MenuBase_OnMenuOpened"> <MenuFlyout x:Key="GameContextMenu" Opened="MenuBase_OnMenuOpened">
@@ -113,8 +114,8 @@
<Style Selector="ListBoxItem"> <Style Selector="ListBoxItem">
<Setter Property="Padding" Value="0" /> <Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="5" /> <Setter Property="Margin" Value="5" />
<Setter Property="CornerRadius" Value="5" /> <Setter Property="CornerRadius" Value="4" />
<Setter Property="Background" Value="{DynamicResource SystemAccentColorDark3}" /> <Setter Property="Background" Value="{DynamicResource AppListBackgroundColor}" />
<Style.Animations> <Style.Animations>
<Animation Duration="0:0:0.7"> <Animation Duration="0:0:0.7">
<KeyFrame Cue="0%"> <KeyFrame Cue="0%">
@@ -132,27 +133,18 @@
</Animation> </Animation>
</Style.Animations> </Style.Animations>
</Style> </Style>
<Style Selector="ListBoxItem:selected /template/ ContentPresenter">
<Setter Property="Background" Value="{DynamicResource AppListBackgroundColor}" />
</Style>
<Style Selector="ListBoxItem:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="{DynamicResource AppListHoverBackgroundColor}" />
</Style>
</ListBox.Styles> </ListBox.Styles>
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<Grid> <Grid>
<Grid.Styles>
<Style Selector="ui|SymbolIcon.small.icon">
<Setter Property="FontSize" Value="15" />
</Style>
<Style Selector="ui|SymbolIcon.normal.icon">
<Setter Property="FontSize" Value="19" />
</Style>
<Style Selector="ui|SymbolIcon.large.icon">
<Setter Property="FontSize" Value="23" />
</Style>
<Style Selector="ui|SymbolIcon.huge.icon">
<Setter Property="FontSize" Value="26" />
</Style>
</Grid.Styles>
<Border <Border
Margin="0" Margin="10"
Padding="{Binding $parent[UserControl].DataContext.GridItemPadding}"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}" Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}"
@@ -160,57 +152,41 @@
Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}" Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}" Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
ClipToBounds="True" ClipToBounds="True"
CornerRadius="5"> CornerRadius="4">
<Grid Margin="0"> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Image <Image
Grid.Row="0" Grid.Row="0"
Margin="0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Top" VerticalAlignment="Top"
Source="{Binding Icon, Converter={StaticResource ByteImage}}" /> Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
<StackPanel <Panel
Grid.Row="1" Grid.Row="1"
Height="50" Height="50"
Margin="5" Margin="0 10 0 0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
IsVisible="{Binding $parent[UserControl].DataContext.ShowNames}"> IsVisible="{Binding $parent[UserControl].DataContext.ShowNames}">
<TextBlock <TextBlock
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Text="{Binding TitleName}" Text="{Binding TitleName}"
TextAlignment="Center" TextAlignment="Center"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
</StackPanel> </Panel>
</Grid> </Grid>
</Border> </Border>
<ui:SymbolIcon <ui:SymbolIcon
Margin="5" Margin="5,5,0,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" VerticalAlignment="Top"
Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}" FontSize="16"
Classes.icon="true" Foreground="{DynamicResource SystemAccentColor}"
Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}"
Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
Foreground="Yellow"
IsVisible="{Binding Favorite}" IsVisible="{Binding Favorite}"
Symbol="StarFilled" /> Symbol="StarFilled" />
<ui:SymbolIcon
Margin="5"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}"
Classes.icon="true"
Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}"
Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
Foreground="Black"
IsVisible="{Binding Favorite}"
Symbol="Star" />
</Grid> </Grid>
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>

View File

@@ -10,7 +10,8 @@
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
d:DesignHeight="450" d:DesignHeight="450"
d:DesignWidth="800" d:DesignWidth="800"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<UserControl.Resources> <UserControl.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" /> <controls:BitmapArrayValueConverter x:Key="ByteImage" />
<MenuFlyout x:Key="GameContextMenu" Opened="MenuBase_OnMenuOpened"> <MenuFlyout x:Key="GameContextMenu" Opened="MenuBase_OnMenuOpened">
@@ -115,7 +116,7 @@
<Setter Property="Padding" Value="0" /> <Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" /> <Setter Property="Margin" Value="0" />
<Setter Property="CornerRadius" Value="5" /> <Setter Property="CornerRadius" Value="5" />
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColorDark3}" /> <Setter Property="Background" Value="{DynamicResource AppListBackgroundColor}" />
<Setter Property="BorderThickness" Value="2"/> <Setter Property="BorderThickness" Value="2"/>
<Style.Animations> <Style.Animations>
<Animation Duration="0:0:0.7"> <Animation Duration="0:0:0.7">
@@ -134,6 +135,12 @@
</Animation> </Animation>
</Style.Animations> </Style.Animations>
</Style> </Style>
<Style Selector="ListBoxItem:selected /template/ ContentPresenter">
<Setter Property="Background" Value="{DynamicResource AppListBackgroundColor}" />
</Style>
<Style Selector="ListBoxItem:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="{DynamicResource AppListHoverBackgroundColor}" />
</Style>
</ListBox.Styles> </ListBox.Styles>
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate> <DataTemplate>
@@ -152,9 +159,6 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Image <Image
Grid.RowSpan="3" Grid.RowSpan="3"
Grid.Column="0" Grid.Column="0"
@@ -214,20 +218,10 @@
Margin="-5,-5,0,0" Margin="-5,-5,0,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" VerticalAlignment="Top"
FontSize="20" FontSize="16"
Foreground="Yellow" Foreground="{DynamicResource SystemAccentColor}"
IsVisible="{Binding Favorite}" IsVisible="{Binding Favorite}"
Symbol="StarFilled" /> Symbol="StarFilled" />
<ui:SymbolIcon
Grid.Row="0"
Grid.Column="0"
Margin="-5,-5,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="20"
Foreground="Black"
IsVisible="{Binding Favorite}"
Symbol="Star" />
</Grid> </Grid>
</Border> </Border>
</Grid> </Grid>

View File

@@ -4,7 +4,8 @@
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: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"> mc:Ignorable="d"
Focusable="True">
<Grid <Grid
Margin="5,10,5,5" Margin="5,10,5,5"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"

View File

@@ -4,7 +4,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 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" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ryujinx.Ava.Ui.Controls.NavigationDialogHost"> x:Class="Ryujinx.Ava.Ui.Controls.NavigationDialogHost"
Focusable="True">
<ui:Frame HorizontalAlignment="Stretch" VerticalAlignment="Stretch" <ui:Frame HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
x:Name="ContentFrame" /> x:Name="ContentFrame" />
</UserControl> </UserControl>

View File

@@ -4,7 +4,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" mc:Ignorable="d"
xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale" xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale"
x:Class="Ryujinx.Ava.Ui.Controls.ProfileImageSelectionDialog"> x:Class="Ryujinx.Ava.Ui.Controls.ProfileImageSelectionDialog"
Focusable="True">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="5,10,5, 5"> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="5,10,5, 5">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />

View File

@@ -3,5 +3,6 @@
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" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ryujinx.Ava.Ui.Controls.RendererHost"> x:Class="Ryujinx.Ava.Ui.Controls.RendererHost"
Focusable="True">
</UserControl> </UserControl>

View File

@@ -9,7 +9,8 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
Height="400" Height="400"
Width="550" Width="550"
x:Class="Ryujinx.Ava.Ui.Controls.SaveManager"> x:Class="Ryujinx.Ava.Ui.Controls.SaveManager"
Focusable="True">
<UserControl.Resources> <UserControl.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" /> <controls:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources> </UserControl.Resources>

View File

@@ -8,7 +8,8 @@
Title="Ryujinx - Waiting" Title="Ryujinx - Waiting"
SizeToContent="WidthAndHeight" SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<Grid <Grid
Margin="20" Margin="20"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"

View File

@@ -12,7 +12,8 @@
Margin="0" Margin="0"
MinWidth="500" MinWidth="500"
Padding="0" Padding="0"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<UserControl.Resources> <UserControl.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" /> <controls:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources> </UserControl.Resources>

View File

@@ -10,7 +10,8 @@
xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale" xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels" xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
x:Class="Ryujinx.Ava.Ui.Controls.UserRecoverer"> x:Class="Ryujinx.Ava.Ui.Controls.UserRecoverer"
Focusable="True">
<Design.DataContext> <Design.DataContext>
<viewModels:UserProfileViewModel /> <viewModels:UserProfileViewModel />
</Design.DataContext> </Design.DataContext>

View File

@@ -12,7 +12,8 @@
d:DesignHeight="450" d:DesignHeight="450"
MinWidth="500" MinWidth="500"
d:DesignWidth="800" d:DesignWidth="800"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<UserControl.Resources> <UserControl.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" /> <controls:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources> </UserControl.Resources>

View File

@@ -436,8 +436,6 @@ namespace Ryujinx.Ava.Ui.ViewModels
} }
} }
public Thickness GridItemPadding => ShowNames ? new Thickness() : new Thickness(5);
public bool ShowMenuAndStatusBar public bool ShowMenuAndStatusBar
{ {
get => _showMenuAndStatusBar; get => _showMenuAndStatusBar;
@@ -599,7 +597,6 @@ namespace Ryujinx.Ava.Ui.ViewModels
ConfigurationState.Instance.Ui.ShowNames.Value = value; ConfigurationState.Instance.Ui.ShowNames.Value = value;
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(GridItemPadding));
OnPropertyChanged(nameof(GridSizeScale)); OnPropertyChanged(nameof(GridSizeScale));
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath); ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
@@ -716,7 +713,6 @@ namespace Ryujinx.Ava.Ui.ViewModels
OnPropertyChanged(nameof(IsGridLarge)); OnPropertyChanged(nameof(IsGridLarge));
OnPropertyChanged(nameof(IsGridHuge)); OnPropertyChanged(nameof(IsGridHuge));
OnPropertyChanged(nameof(ShowNames)); OnPropertyChanged(nameof(ShowNames));
OnPropertyChanged(nameof(GridItemPadding));
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath); ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
} }
@@ -780,6 +776,11 @@ namespace Ryujinx.Ava.Ui.ViewModels
{ {
_owner.LoadProgressBar.IsVisible = false; _owner.LoadProgressBar.IsVisible = false;
} }
if (e.NumAppsLoaded == e.NumAppsFound)
{
_owner.LoadProgressBar.IsVisible = false;
}
}); });
} }

View File

@@ -15,7 +15,8 @@
CanResize="False" CanResize="False"
SizeToContent="Width" SizeToContent="Width"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<Grid <Grid
Margin="15" Margin="15"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"

View File

@@ -11,7 +11,8 @@
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
Width="800" MinHeight="650" Height="650" Width="800" MinHeight="650" Height="650"
SizeToContent="Manual" SizeToContent="Manual"
MinWidth="600"> MinWidth="600"
Focusable="True">
<Design.DataContext> <Design.DataContext>
<viewModels:AmiiboWindowViewModel /> <viewModels:AmiiboWindowViewModel />
</Design.DataContext> </Design.DataContext>

View File

@@ -11,7 +11,8 @@
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels" xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls" xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
x:CompileBindings="True" x:CompileBindings="True"
x:DataType="viewModels:AvatarProfileViewModel"> x:DataType="viewModels:AvatarProfileViewModel"
Focusable="True">
<Design.DataContext> <Design.DataContext>
<viewModels:AvatarProfileViewModel /> <viewModels:AvatarProfileViewModel />
</Design.DataContext> </Design.DataContext>

View File

@@ -12,7 +12,8 @@
MinWidth="500" MinWidth="500"
MinHeight="500" MinHeight="500"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<Window.Styles> <Window.Styles>
<Style Selector="TreeViewItem"> <Style Selector="TreeViewItem">
<Setter Property="IsExpanded" Value="True" /> <Setter Property="IsExpanded" Value="True" />

View File

@@ -8,7 +8,8 @@
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
x:Class="Ryujinx.Ava.Ui.Windows.ContentDialogOverlayWindow" x:Class="Ryujinx.Ava.Ui.Windows.ContentDialogOverlayWindow"
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows" xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
Title="ContentDialogOverlayWindow"> Title="ContentDialogOverlayWindow"
Focusable="True">
<window:StyleableWindow.Styles> <window:StyleableWindow.Styles>
<Style Selector="ui|ContentDialog /template/ Panel#LayoutRoot"> <Style Selector="ui|ContentDialog /template/ Panel#LayoutRoot">
<Setter Property="Background" <Setter Property="Background"

View File

@@ -13,7 +13,8 @@
d:DesignHeight="800" d:DesignHeight="800"
d:DesignWidth="800" d:DesignWidth="800"
x:CompileBindings="False" x:CompileBindings="False"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<Design.DataContext> <Design.DataContext>
<viewModels:ControllerSettingsViewModel /> <viewModels:ControllerSettingsViewModel />
</Design.DataContext> </Design.DataContext>

View File

@@ -14,7 +14,8 @@
MaxHeight="500" MaxHeight="500"
SizeToContent="Height" SizeToContent="Height"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<Grid Name="DownloadableContentGrid" Margin="15"> <Grid Name="DownloadableContentGrid" Margin="15">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />

View File

@@ -20,7 +20,7 @@ namespace Ryujinx.Ava.Ui.Windows
private const int CutOffLuminosity = 64; private const int CutOffLuminosity = 64;
private struct PaletteColor private readonly struct PaletteColor
{ {
public int Qck { get; } public int Qck { get; }
public byte R { get; } public byte R { get; }

View File

@@ -20,7 +20,8 @@
x:CompileBindings="True" x:CompileBindings="True"
x:DataType="viewModels:MainWindowViewModel" x:DataType="viewModels:MainWindowViewModel"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<Window.Styles> <Window.Styles>
<Style Selector="TitleBar:fullscreen"> <Style Selector="TitleBar:fullscreen">
<Setter Property="Background" Value="#000000" /> <Setter Property="Background" Value="#000000" />

View File

@@ -266,6 +266,7 @@ namespace Ryujinx.Ava.Ui.Windows
return; return;
} }
CanUpdate = false;
ViewModel.LoadHeading = string.IsNullOrWhiteSpace(titleName) ? string.Format(LocaleManager.Instance["LoadingHeading"], AppHost.Device.Application.TitleName) : titleName; ViewModel.LoadHeading = string.IsNullOrWhiteSpace(titleName) ? string.Format(LocaleManager.Instance["LoadingHeading"], AppHost.Device.Application.TitleName) : titleName;
ViewModel.TitleName = string.IsNullOrWhiteSpace(titleName) ? AppHost.Device.Application.TitleName : titleName; ViewModel.TitleName = string.IsNullOrWhiteSpace(titleName) ? AppHost.Device.Application.TitleName : titleName;
@@ -371,6 +372,7 @@ namespace Ryujinx.Ava.Ui.Windows
ViewModel.ShowContent = true; ViewModel.ShowContent = true;
ViewModel.ShowLoadProgress = false; ViewModel.ShowLoadProgress = false;
ViewModel.IsLoadingIndeterminate = false; ViewModel.IsLoadingIndeterminate = false;
CanUpdate = true;
Cursor = Cursor.Default; Cursor = Cursor.Default;
if (MainContent.Content != _mainViewContent) if (MainContent.Content != _mainViewContent)

View File

@@ -6,7 +6,8 @@
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale" xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
mc:Ignorable="d" mc:Ignorable="d"
x:Class="Ryujinx.Ava.Ui.Windows.MotionSettingsWindow"> x:Class="Ryujinx.Ava.Ui.Windows.MotionSettingsWindow"
Focusable="True">
<Grid Margin="10"> <Grid Margin="10">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />

View File

@@ -6,7 +6,8 @@
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale" xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
mc:Ignorable="d" mc:Ignorable="d"
x:Class="Ryujinx.Ava.Ui.Windows.RumbleSettingsWindow"> x:Class="Ryujinx.Ava.Ui.Windows.RumbleSettingsWindow"
Focusable="True">
<Grid Margin="10"> <Grid Margin="10">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />

View File

@@ -18,7 +18,8 @@
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
x:CompileBindings="True" x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel" x:DataType="viewModels:SettingsViewModel"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<Design.DataContext> <Design.DataContext>
<viewModels:SettingsViewModel /> <viewModels:SettingsViewModel />
</Design.DataContext> </Design.DataContext>

View File

@@ -14,7 +14,8 @@
MaxHeight="400" MaxHeight="400"
SizeToContent="Height" SizeToContent="Height"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
mc:Ignorable="d"> mc:Ignorable="d"
Focusable="True">
<Grid Margin="15"> <Grid Margin="15">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />

View File

@@ -16,7 +16,7 @@ namespace Ryujinx.Common.Logging
public static event EventHandler<LogEventArgs> Updated; public static event EventHandler<LogEventArgs> Updated;
public struct Log public readonly struct Log
{ {
internal readonly LogLevel Level; internal readonly LogLevel Level;

View File

@@ -7,7 +7,7 @@ namespace Ryujinx.Common.Memory
/// This is useful to keep the Array representation when possible to avoid copies. /// This is useful to keep the Array representation when possible to avoid copies.
/// </summary> /// </summary>
/// <typeparam name="T">Element Type</typeparam> /// <typeparam name="T">Element Type</typeparam>
public ref struct SpanOrArray<T> where T : unmanaged public readonly ref struct SpanOrArray<T> where T : unmanaged
{ {
public readonly T[] Array; public readonly T[] Array;
public readonly ReadOnlySpan<T> Span; public readonly ReadOnlySpan<T> Span;

View File

@@ -17,7 +17,7 @@ namespace Ryujinx.Cpu
/// <summary> /// <summary>
/// Stores handlers for the various CPU exceptions. /// Stores handlers for the various CPU exceptions.
/// </summary> /// </summary>
public struct ExceptionCallbacks public readonly struct ExceptionCallbacks
{ {
/// <summary> /// <summary>
/// Handler for CPU interrupts triggered using <see cref="IExecutionContext.RequestInterrupt"/>. /// Handler for CPU interrupts triggered using <see cref="IExecutionContext.RequestInterrupt"/>.

View File

@@ -2,7 +2,7 @@
namespace Ryujinx.Graphics.Device namespace Ryujinx.Graphics.Device
{ {
public struct RwCallback public readonly struct RwCallback
{ {
public Action<int> Write { get; } public Action<int> Write { get; }
public Func<int> Read { get; } public Func<int> Read { get; }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct BlendDescriptor public readonly struct BlendDescriptor
{ {
public bool Enable { get; } public bool Enable { get; }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct BufferAssignment public readonly struct BufferAssignment
{ {
public readonly int Binding; public readonly int Binding;
public readonly BufferRange Range; public readonly BufferRange Range;

View File

@@ -1,22 +1,14 @@
using System; using System.Runtime.InteropServices;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
[StructLayout(LayoutKind.Sequential, Size = 8)] [StructLayout(LayoutKind.Sequential, Size = 8)]
public struct BufferHandle : IEquatable<BufferHandle> public readonly record struct BufferHandle
{ {
private readonly ulong _value; private readonly ulong _value;
public static BufferHandle Null => new BufferHandle(0); public static BufferHandle Null => new BufferHandle(0);
private BufferHandle(ulong value) => _value = value; private BufferHandle(ulong value) => _value = value;
public override bool Equals(object obj) => obj is BufferHandle handle && Equals(handle);
public bool Equals([AllowNull] BufferHandle other) => other._value == _value;
public override int GetHashCode() => _value.GetHashCode();
public static bool operator ==(BufferHandle left, BufferHandle right) => left.Equals(right);
public static bool operator !=(BufferHandle left, BufferHandle right) => !(left == right);
} }
} }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct BufferRange public readonly struct BufferRange
{ {
private static readonly BufferRange _empty = new BufferRange(BufferHandle.Null, 0, 0); private static readonly BufferRange _empty = new BufferRange(BufferHandle.Null, 0, 0);

View File

@@ -2,7 +2,7 @@ using Ryujinx.Graphics.Shader.Translation;
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct Capabilities public readonly struct Capabilities
{ {
public readonly TargetApi Api; public readonly TargetApi Api;
public readonly string VendorName; public readonly string VendorName;
@@ -17,6 +17,7 @@ namespace Ryujinx.Graphics.GAL
public readonly bool Supports3DTextureCompression; public readonly bool Supports3DTextureCompression;
public readonly bool SupportsBgraFormat; public readonly bool SupportsBgraFormat;
public readonly bool SupportsR4G4Format; public readonly bool SupportsR4G4Format;
public readonly bool SupportsSnormBufferTextureFormat;
public readonly bool SupportsFragmentShaderInterlock; public readonly bool SupportsFragmentShaderInterlock;
public readonly bool SupportsFragmentShaderOrderingIntel; public readonly bool SupportsFragmentShaderOrderingIntel;
public readonly bool SupportsGeometryShaderPassthrough; public readonly bool SupportsGeometryShaderPassthrough;
@@ -52,6 +53,7 @@ namespace Ryujinx.Graphics.GAL
bool supports3DTextureCompression, bool supports3DTextureCompression,
bool supportsBgraFormat, bool supportsBgraFormat,
bool supportsR4G4Format, bool supportsR4G4Format,
bool supportsSnormBufferTextureFormat,
bool supportsFragmentShaderInterlock, bool supportsFragmentShaderInterlock,
bool supportsFragmentShaderOrderingIntel, bool supportsFragmentShaderOrderingIntel,
bool supportsGeometryShaderPassthrough, bool supportsGeometryShaderPassthrough,
@@ -84,6 +86,7 @@ namespace Ryujinx.Graphics.GAL
Supports3DTextureCompression = supports3DTextureCompression; Supports3DTextureCompression = supports3DTextureCompression;
SupportsBgraFormat = supportsBgraFormat; SupportsBgraFormat = supportsBgraFormat;
SupportsR4G4Format = supportsR4G4Format; SupportsR4G4Format = supportsR4G4Format;
SupportsSnormBufferTextureFormat = supportsSnormBufferTextureFormat;
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock; SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel; SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough; SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;

View File

@@ -1,32 +1,4 @@
using System;
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct ColorF : IEquatable<ColorF> public readonly record struct ColorF(float Red, float Green, float Blue, float Alpha);
{
public float Red { get; }
public float Green { get; }
public float Blue { get; }
public float Alpha { get; }
public ColorF(float red, float green, float blue, float alpha)
{
Red = red;
Green = green;
Blue = blue;
Alpha = alpha;
}
public bool Equals(ColorF color) => Red == color.Red &&
Green == color.Green &&
Blue == color.Blue &&
Alpha == color.Alpha;
public override bool Equals(object obj) => (obj is ColorF color) && Equals(color);
public override int GetHashCode() => HashCode.Combine(Red, Green, Blue, Alpha);
public static bool operator ==(ColorF l, ColorF r) => l.Equals(r);
public static bool operator !=(ColorF l, ColorF r) => !l.Equals(r);
}
} }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct DepthTestDescriptor public readonly struct DepthTestDescriptor
{ {
public bool TestEnable { get; } public bool TestEnable { get; }
public bool WriteEnable { get; } public bool WriteEnable { get; }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct DeviceInfo public readonly struct DeviceInfo
{ {
public readonly string Id; public readonly string Id;
public readonly string Vendor; public readonly string Vendor;

View File

@@ -2,7 +2,7 @@ using Ryujinx.Common;
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct Extents2D public readonly struct Extents2D
{ {
public int X1 { get; } public int X1 { get; }
public int Y1 { get; } public int Y1 { get; }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct Extents2DF public readonly struct Extents2DF
{ {
public float X1 { get; } public float X1 { get; }
public float Y1 { get; } public float Y1 { get; }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct HardwareInfo public readonly struct HardwareInfo
{ {
public string GpuVendor { get; } public string GpuVendor { get; }
public string GpuModel { get; } public string GpuModel { get; }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct ImageCrop public readonly struct ImageCrop
{ {
public int Left { get; } public int Left { get; }
public int Right { get; } public int Right { get; }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct MultisampleDescriptor public readonly struct MultisampleDescriptor
{ {
public bool AlphaToCoverageEnable { get; } public bool AlphaToCoverageEnable { get; }
public bool AlphaToCoverageDitherEnable { get; } public bool AlphaToCoverageDitherEnable { get; }

View File

@@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.GAL
/// <summary> /// <summary>
/// Descriptor for a pipeline buffer binding. /// Descriptor for a pipeline buffer binding.
/// </summary> /// </summary>
public struct BufferPipelineDescriptor public readonly struct BufferPipelineDescriptor
{ {
public bool Enable { get; } public bool Enable { get; }
public int Stride { get; } public int Stride { get; }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct Rectangle<T> where T : unmanaged public readonly struct Rectangle<T> where T : unmanaged
{ {
public T X { get; } public T X { get; }
public T Y { get; } public T Y { get; }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct SamplerCreateInfo public readonly struct SamplerCreateInfo
{ {
public MinFilter MinFilter { get; } public MinFilter MinFilter { get; }
public MagFilter MagFilter { get; } public MagFilter MagFilter { get; }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct ScreenCaptureImageInfo public readonly struct ScreenCaptureImageInfo
{ {
public ScreenCaptureImageInfo(int width, int height, bool isBgra, byte[] data, bool flipX, bool flipY) public ScreenCaptureImageInfo(int width, int height, bool isBgra, byte[] data, bool flipX, bool flipY)
{ {

View File

@@ -2,7 +2,7 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct ShaderBindings public readonly struct ShaderBindings
{ {
public IReadOnlyCollection<int> UniformBufferBindings { get; } public IReadOnlyCollection<int> UniformBufferBindings { get; }
public IReadOnlyCollection<int> StorageBufferBindings { get; } public IReadOnlyCollection<int> StorageBufferBindings { get; }

View File

@@ -3,7 +3,7 @@ using Ryujinx.Graphics.Shader.Translation;
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct ShaderSource public readonly struct ShaderSource
{ {
public string Code { get; } public string Code { get; }
public byte[] BinaryCode { get; } public byte[] BinaryCode { get; }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct StencilTestDescriptor public readonly struct StencilTestDescriptor
{ {
public bool TestEnable { get; } public bool TestEnable { get; }

View File

@@ -4,7 +4,7 @@ using System.Numerics;
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct TextureCreateInfo : IEquatable<TextureCreateInfo> public readonly struct TextureCreateInfo : IEquatable<TextureCreateInfo>
{ {
public int Width { get; } public int Width { get; }
public int Height { get; } public int Height { get; }
@@ -62,42 +62,42 @@ namespace Ryujinx.Graphics.GAL
SwizzleA = swizzleA; SwizzleA = swizzleA;
} }
public readonly int GetMipSize(int level) public int GetMipSize(int level)
{ {
return GetMipStride(level) * GetLevelHeight(level) * GetLevelDepth(level); return GetMipStride(level) * GetLevelHeight(level) * GetLevelDepth(level);
} }
public readonly int GetMipSize2D(int level) public int GetMipSize2D(int level)
{ {
return GetMipStride(level) * GetLevelHeight(level); return GetMipStride(level) * GetLevelHeight(level);
} }
public readonly int GetMipStride(int level) public int GetMipStride(int level)
{ {
return BitUtils.AlignUp(GetLevelWidth(level) * BytesPerPixel, 4); return BitUtils.AlignUp(GetLevelWidth(level) * BytesPerPixel, 4);
} }
private readonly int GetLevelWidth(int level) private int GetLevelWidth(int level)
{ {
return BitUtils.DivRoundUp(GetLevelSize(Width, level), BlockWidth); return BitUtils.DivRoundUp(GetLevelSize(Width, level), BlockWidth);
} }
private readonly int GetLevelHeight(int level) private int GetLevelHeight(int level)
{ {
return BitUtils.DivRoundUp(GetLevelSize(Height, level), BlockHeight); return BitUtils.DivRoundUp(GetLevelSize(Height, level), BlockHeight);
} }
private readonly int GetLevelDepth(int level) private int GetLevelDepth(int level)
{ {
return Target == Target.Texture3D ? GetLevelSize(Depth, level) : GetLayers(); return Target == Target.Texture3D ? GetLevelSize(Depth, level) : GetLayers();
} }
public readonly int GetDepthOrLayers() public int GetDepthOrLayers()
{ {
return Target == Target.Texture3D ? Depth : GetLayers(); return Target == Target.Texture3D ? Depth : GetLayers();
} }
public readonly int GetLayers() public int GetLayers()
{ {
if (Target == Target.Texture2DArray || if (Target == Target.Texture2DArray ||
Target == Target.Texture2DMultisampleArray || Target == Target.Texture2DMultisampleArray ||
@@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.GAL
return 1; return 1;
} }
public readonly int GetLevelsClamped() public int GetLevelsClamped()
{ {
int maxSize = Width; int maxSize = Width;

View File

@@ -1,40 +1,4 @@
using System;
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct VertexAttribDescriptor : IEquatable<VertexAttribDescriptor> public readonly record struct VertexAttribDescriptor(int BufferIndex, int Offset, bool IsZero, Format Format);
{
public int BufferIndex { get; }
public int Offset { get; }
public bool IsZero { get; }
public Format Format { get; }
public VertexAttribDescriptor(int bufferIndex, int offset, bool isZero, Format format)
{
BufferIndex = bufferIndex;
Offset = offset;
IsZero = isZero;
Format = format;
}
public override bool Equals(object obj)
{
return obj is VertexAttribDescriptor other && Equals(other);
}
public bool Equals(VertexAttribDescriptor other)
{
return BufferIndex == other.BufferIndex &&
Offset == other.Offset &&
IsZero == other.IsZero &&
Format == other.Format;
}
public override int GetHashCode()
{
return HashCode.Combine(BufferIndex, Offset, IsZero, Format);
}
}
} }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct VertexBufferDescriptor public readonly struct VertexBufferDescriptor
{ {
public BufferRange Buffer { get; } public BufferRange Buffer { get; }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
public struct Viewport public readonly struct Viewport
{ {
public Rectangle<float> Region { get; } public Rectangle<float> Region { get; }

View File

@@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
/// <summary> /// <summary>
/// FIFO word. /// FIFO word.
/// </summary> /// </summary>
struct FifoWord readonly struct FifoWord
{ {
/// <summary> /// <summary>
/// GPU virtual address where the word is located in memory. /// GPU virtual address where the word is located in memory.

View File

@@ -13,7 +13,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
/// <summary> /// <summary>
/// Macroo High-level implementation table entry. /// Macroo High-level implementation table entry.
/// </summary> /// </summary>
struct TableEntry readonly struct TableEntry
{ {
/// <summary> /// <summary>
/// Name of the Macro function. /// Name of the Macro function.

View File

@@ -19,6 +19,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
private readonly GpuChannel _channel; private readonly GpuChannel _channel;
private readonly DeviceStateWithShadow<ThreedClassState> _state; private readonly DeviceStateWithShadow<ThreedClassState> _state;
private readonly DrawState _drawState; private readonly DrawState _drawState;
private readonly SpecializationStateUpdater _currentSpecState;
private bool _topologySet; private bool _topologySet;
private bool _instancedDrawPending; private bool _instancedDrawPending;
@@ -44,12 +45,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// <param name="channel">GPU channel</param> /// <param name="channel">GPU channel</param>
/// <param name="state">Channel state</param> /// <param name="state">Channel state</param>
/// <param name="drawState">Draw state</param> /// <param name="drawState">Draw state</param>
public DrawManager(GpuContext context, GpuChannel channel, DeviceStateWithShadow<ThreedClassState> state, DrawState drawState) /// <param name="spec">Specialization state updater</param>
public DrawManager(GpuContext context, GpuChannel channel, DeviceStateWithShadow<ThreedClassState> state, DrawState drawState, SpecializationStateUpdater spec)
{ {
_context = context; _context = context;
_channel = channel; _channel = channel;
_state = state; _state = state;
_drawState = drawState; _drawState = drawState;
_currentSpecState = spec;
} }
/// <summary> /// <summary>
@@ -132,6 +135,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_drawState.FirstIndex = firstIndex; _drawState.FirstIndex = firstIndex;
_drawState.IndexCount = indexCount; _drawState.IndexCount = indexCount;
_currentSpecState.SetHasConstantBufferDrawParameters(false);
engine.UpdateState(); engine.UpdateState();
@@ -256,6 +260,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
if (_drawState.Topology != topology || !_topologySet) if (_drawState.Topology != topology || !_topologySet)
{ {
_context.Renderer.Pipeline.SetPrimitiveTopology(topology); _context.Renderer.Pipeline.SetPrimitiveTopology(topology);
_currentSpecState.SetTopology(topology);
_drawState.Topology = topology; _drawState.Topology = topology;
_topologySet = true; _topologySet = true;
} }
@@ -452,7 +457,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_state.State.FirstInstance = (uint)firstInstance; _state.State.FirstInstance = (uint)firstInstance;
_drawState.DrawIndexed = indexed; _drawState.DrawIndexed = indexed;
_drawState.HasConstantBufferDrawParameters = true; _currentSpecState.SetHasConstantBufferDrawParameters(true);
engine.UpdateState(); engine.UpdateState();
@@ -469,7 +474,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_state.State.FirstInstance = 0; _state.State.FirstInstance = 0;
_drawState.DrawIndexed = false; _drawState.DrawIndexed = false;
_drawState.HasConstantBufferDrawParameters = false;
if (renderEnable == ConditionalRenderEnabled.Host) if (renderEnable == ConditionalRenderEnabled.Host)
{ {
@@ -527,7 +531,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_drawState.DrawIndexed = indexed; _drawState.DrawIndexed = indexed;
_drawState.DrawIndirect = true; _drawState.DrawIndirect = true;
_drawState.HasConstantBufferDrawParameters = true; _currentSpecState.SetHasConstantBufferDrawParameters(true);
engine.UpdateState(); engine.UpdateState();
@@ -561,7 +565,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_drawState.DrawIndexed = false; _drawState.DrawIndexed = false;
_drawState.DrawIndirect = false; _drawState.DrawIndirect = false;
_drawState.HasConstantBufferDrawParameters = false;
if (renderEnable == ConditionalRenderEnabled.Host) if (renderEnable == ConditionalRenderEnabled.Host)
{ {

View File

@@ -0,0 +1,280 @@
using Ryujinx.Common.Memory;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Shader;
using Ryujinx.Graphics.Shader;
namespace Ryujinx.Graphics.Gpu.Engine.Threed
{
/// <summary>
/// Maintains a "current" specialiation state, and provides a flag to check if it has changed meaningfully.
/// </summary>
internal class SpecializationStateUpdater
{
private GpuChannelGraphicsState _graphics;
private GpuChannelPoolState _pool;
private bool _usesDrawParameters;
private bool _usesTopology;
private bool _changed;
/// <summary>
/// Signal that the specialization state has changed.
/// </summary>
private void Signal()
{
_changed = true;
}
/// <summary>
/// Checks if the specialization state has changed since the last check.
/// </summary>
/// <returns>True if it has changed, false otherwise</returns>
public bool HasChanged()
{
if (_changed)
{
_changed = false;
return true;
}
else
{
return false;
}
}
/// <summary>
/// Sets the active shader, clearing the dirty state and recording if certain specializations are noteworthy.
/// </summary>
/// <param name="gs">The active shader</param>
public void SetShader(CachedShaderProgram gs)
{
_usesDrawParameters = gs.Shaders[1]?.Info.UsesDrawParameters ?? false;
_usesTopology = gs.SpecializationState.IsPrimitiveTopologyQueried();
_changed = false;
}
/// <summary>
/// Get the current graphics state.
/// </summary>
/// <returns>GPU graphics state</returns>
public ref GpuChannelGraphicsState GetGraphicsState()
{
return ref _graphics;
}
/// <summary>
/// Get the current pool state.
/// </summary>
/// <returns>GPU pool state</returns>
public ref GpuChannelPoolState GetPoolState()
{
return ref _pool;
}
/// <summary>
/// Early Z force enable.
/// </summary>
/// <param name="value">The new value</param>
public void SetEarlyZForce(bool value)
{
_graphics.EarlyZForce = value;
Signal();
}
/// <summary>
/// Primitive topology of current draw.
/// </summary>
/// <param name="value">The new value</param>
public void SetTopology(PrimitiveTopology value)
{
if (value != _graphics.Topology)
{
_graphics.Topology = value;
if (_usesTopology)
{
Signal();
}
}
}
/// <summary>
/// Tessellation mode.
/// </summary>
/// <param name="value">The new value</param>
public void SetTessellationMode(TessMode value)
{
if (value.Packed != _graphics.TessellationMode.Packed)
{
_graphics.TessellationMode = value;
Signal();
}
}
/// <summary>
/// Updates alpha-to-coverage state, and sets it as changed.
/// </summary>
/// <param name="enable">Whether alpha-to-coverage is enabled</param>
/// <param name="ditherEnable">Whether alpha-to-coverage dithering is enabled</param>
public void SetAlphaToCoverageEnable(bool enable, bool ditherEnable)
{
_graphics.AlphaToCoverageEnable = enable;
_graphics.AlphaToCoverageDitherEnable = ditherEnable;
Signal();
}
/// <summary>
/// Indicates whether the viewport transform is disabled.
/// </summary>
/// <param name="value">The new value</param>
public void SetViewportTransformDisable(bool value)
{
if (value != _graphics.ViewportTransformDisable)
{
_graphics.ViewportTransformDisable = value;
Signal();
}
}
/// <summary>
/// Depth mode zero to one or minus one to one.
/// </summary>
/// <param name="value">The new value</param>
public void SetDepthMode(bool value)
{
if (value != _graphics.DepthMode)
{
_graphics.DepthMode = value;
Signal();
}
}
/// <summary>
/// Indicates if the point size is set on the shader or is fixed.
/// </summary>
/// <param name="value">The new value</param>
public void SetProgramPointSizeEnable(bool value)
{
if (value != _graphics.ProgramPointSizeEnable)
{
_graphics.ProgramPointSizeEnable = value;
Signal();
}
}
/// <summary>
/// Point size used if <see cref="SetProgramPointSizeEnable" /> is provided false.
/// </summary>
/// <param name="value">The new value</param>
public void SetPointSize(float value)
{
if (value != _graphics.PointSize)
{
_graphics.PointSize = value;
Signal();
}
}
/// <summary>
/// Updates alpha test specialization state, and sets it as changed.
/// </summary>
/// <param name="enable">Whether alpha test is enabled</param>
/// <param name="reference">The value to compare with the fragment output alpha</param>
/// <param name="op">The comparison that decides if the fragment should be discarded</param>
public void SetAlphaTest(bool enable, float reference, CompareOp op)
{
_graphics.AlphaTestEnable = enable;
_graphics.AlphaTestReference = reference;
_graphics.AlphaTestCompare = op;
Signal();
}
/// <summary>
/// Updates the type of the vertex attributes consumed by the shader.
/// </summary>
/// <param name="state">The new state</param>
public void SetAttributeTypes(ref Array32<VertexAttribState> state)
{
bool changed = false;
ref Array32<AttributeType> attributeTypes = ref _graphics.AttributeTypes;
for (int location = 0; location < state.Length; location++)
{
VertexAttribType type = state[location].UnpackType();
AttributeType value = type switch
{
VertexAttribType.Sint => AttributeType.Sint,
VertexAttribType.Uint => AttributeType.Uint,
_ => AttributeType.Float
};
if (attributeTypes[location] != value)
{
attributeTypes[location] = value;
changed = true;
}
}
if (changed)
{
Signal();
}
}
/// <summary>
/// Indicates that the draw is writing the base vertex, base instance and draw index to Constant Buffer 0.
/// </summary>
/// <param name="value">The new value</param>
public void SetHasConstantBufferDrawParameters(bool value)
{
if (value != _graphics.HasConstantBufferDrawParameters)
{
_graphics.HasConstantBufferDrawParameters = value;
if (_usesDrawParameters)
{
Signal();
}
}
}
/// <summary>
/// Indicates that any storage buffer use is unaligned.
/// </summary>
/// <param name="value">The new value</param>
public void SetHasUnalignedStorageBuffer(bool value)
{
if (value != _graphics.HasUnalignedStorageBuffer)
{
_graphics.HasUnalignedStorageBuffer = value;
Signal();
}
}
/// <summary>
/// Sets the GPU pool state.
/// </summary>
/// <param name="state">The new state</param>
public void SetPoolState(GpuChannelPoolState state)
{
if (!state.Equals(_pool))
{
_pool = state;
Signal();
}
}
}
}

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// <summary> /// <summary>
/// State update callback entry, with the callback function and associated field names. /// State update callback entry, with the callback function and associated field names.
/// </summary> /// </summary>
struct StateUpdateCallbackEntry readonly struct StateUpdateCallbackEntry
{ {
/// <summary> /// <summary>
/// Callback function, to be called if the register was written as the state needs to be updated. /// Callback function, to be called if the register was written as the state needs to be updated.

View File

@@ -1,6 +1,7 @@
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Engine.GPFifo;
using Ryujinx.Graphics.Gpu.Engine.Types; using Ryujinx.Graphics.Gpu.Engine.Types;
using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Gpu.Image;
using Ryujinx.Graphics.Gpu.Shader; using Ryujinx.Graphics.Gpu.Shader;
@@ -16,9 +17,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// </summary> /// </summary>
class StateUpdater class StateUpdater
{ {
public const int ShaderStateIndex = 16; public const int ShaderStateIndex = 26;
public const int RasterizerStateIndex = 15; public const int RasterizerStateIndex = 15;
public const int ScissorStateIndex = 18; public const int ScissorStateIndex = 16;
public const int VertexBufferStateIndex = 0; public const int VertexBufferStateIndex = 0;
public const int PrimitiveRestartStateIndex = 12; public const int PrimitiveRestartStateIndex = 12;
@@ -31,6 +32,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
private readonly ShaderProgramInfo[] _currentProgramInfo; private readonly ShaderProgramInfo[] _currentProgramInfo;
private ShaderSpecializationState _shaderSpecState; private ShaderSpecializationState _shaderSpecState;
private SpecializationStateUpdater _currentSpecState;
private ProgramPipelineState _pipeline; private ProgramPipelineState _pipeline;
@@ -54,15 +56,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// <param name="channel">GPU channel</param> /// <param name="channel">GPU channel</param>
/// <param name="state">3D engine state</param> /// <param name="state">3D engine state</param>
/// <param name="drawState">Draw state</param> /// <param name="drawState">Draw state</param>
public StateUpdater(GpuContext context, GpuChannel channel, DeviceStateWithShadow<ThreedClassState> state, DrawState drawState) /// <param name="spec">Specialization state updater</param>
public StateUpdater(GpuContext context, GpuChannel channel, DeviceStateWithShadow<ThreedClassState> state, DrawState drawState, SpecializationStateUpdater spec)
{ {
_context = context; _context = context;
_channel = channel; _channel = channel;
_state = state; _state = state;
_drawState = drawState; _drawState = drawState;
_currentProgramInfo = new ShaderProgramInfo[Constants.ShaderStages]; _currentProgramInfo = new ShaderProgramInfo[Constants.ShaderStages];
_currentSpecState = spec;
// ShaderState must be updated after other state updates, as pipeline state is sent to the backend when compiling new shaders. // ShaderState must be updated after other state updates, as specialization/pipeline state is used when fetching shaders.
// Render target state must appear after shader state as it depends on information from the currently bound shader. // Render target state must appear after shader state as it depends on information from the currently bound shader.
// Rasterizer and scissor states are checked by render target clear, their indexes // Rasterizer and scissor states are checked by render target clear, their indexes
// must be updated on the constants "RasterizerStateIndex" and "ScissorStateIndex" if modified. // must be updated on the constants "RasterizerStateIndex" and "ScissorStateIndex" if modified.
@@ -101,6 +105,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
nameof(ThreedClassState.DepthTestFunc)), nameof(ThreedClassState.DepthTestFunc)),
new StateUpdateCallbackEntry(UpdateTessellationState, new StateUpdateCallbackEntry(UpdateTessellationState,
nameof(ThreedClassState.TessMode),
nameof(ThreedClassState.TessOuterLevel), nameof(ThreedClassState.TessOuterLevel),
nameof(ThreedClassState.TessInnerLevel), nameof(ThreedClassState.TessInnerLevel),
nameof(ThreedClassState.PatchVertices)), nameof(ThreedClassState.PatchVertices)),
@@ -138,17 +143,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
new StateUpdateCallbackEntry(UpdateRasterizerState, nameof(ThreedClassState.RasterizeEnable)), new StateUpdateCallbackEntry(UpdateRasterizerState, nameof(ThreedClassState.RasterizeEnable)),
new StateUpdateCallbackEntry(UpdateShaderState,
nameof(ThreedClassState.ShaderBaseAddress),
nameof(ThreedClassState.ShaderState)),
new StateUpdateCallbackEntry(UpdateRenderTargetState,
nameof(ThreedClassState.RtColorState),
nameof(ThreedClassState.RtDepthStencilState),
nameof(ThreedClassState.RtControl),
nameof(ThreedClassState.RtDepthStencilSize),
nameof(ThreedClassState.RtDepthStencilEnable)),
new StateUpdateCallbackEntry(UpdateScissorState, new StateUpdateCallbackEntry(UpdateScissorState,
nameof(ThreedClassState.ScissorState), nameof(ThreedClassState.ScissorState),
nameof(ThreedClassState.ScreenScissorState)), nameof(ThreedClassState.ScreenScissorState)),
@@ -179,7 +173,21 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
new StateUpdateCallbackEntry(UpdateMultisampleState, new StateUpdateCallbackEntry(UpdateMultisampleState,
nameof(ThreedClassState.AlphaToCoverageDitherEnable), nameof(ThreedClassState.AlphaToCoverageDitherEnable),
nameof(ThreedClassState.MultisampleControl)) nameof(ThreedClassState.MultisampleControl)),
new StateUpdateCallbackEntry(UpdateEarlyZState,
nameof(ThreedClassState.EarlyZForce)),
new StateUpdateCallbackEntry(UpdateShaderState,
nameof(ThreedClassState.ShaderBaseAddress),
nameof(ThreedClassState.ShaderState)),
new StateUpdateCallbackEntry(UpdateRenderTargetState,
nameof(ThreedClassState.RtColorState),
nameof(ThreedClassState.RtDepthStencilState),
nameof(ThreedClassState.RtControl),
nameof(ThreedClassState.RtDepthStencilSize),
nameof(ThreedClassState.RtDepthStencilEnable)),
}); });
} }
@@ -209,17 +217,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Update() public void Update()
{ {
// If any state that the shader depends on changed,
// then we may need to compile/bind a different version
// of the shader for the new state.
if (_shaderSpecState != null)
{
if (!_shaderSpecState.MatchesGraphics(_channel, GetPoolState(), GetGraphicsState(), _vsUsesDrawParameters, false))
{
ForceShaderUpdate();
}
}
// The vertex buffer size is calculated using a different // The vertex buffer size is calculated using a different
// method when doing indexed draws, so we need to make sure // method when doing indexed draws, so we need to make sure
// to update the vertex buffers if we are doing a regular // to update the vertex buffers if we are doing a regular
@@ -271,6 +268,18 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_updateTracker.Update(ulong.MaxValue); _updateTracker.Update(ulong.MaxValue);
// If any state that the shader depends on changed,
// then we may need to compile/bind a different version
// of the shader for the new state.
if (_shaderSpecState != null && _currentSpecState.HasChanged())
{
if (!_shaderSpecState.MatchesGraphics(_channel, ref _currentSpecState.GetPoolState(), ref _currentSpecState.GetGraphicsState(), _vsUsesDrawParameters, false))
{
// Shader must be reloaded. _vtgWritesRtLayer should not change.
UpdateShaderState();
}
}
CommitBindings(); CommitBindings();
if (tfEnable && !_prevTfEnable) if (tfEnable && !_prevTfEnable)
@@ -302,7 +311,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
if (!_channel.TextureManager.CommitGraphicsBindings(_shaderSpecState) || (buffers.HasUnalignedStorageBuffers != hasUnaligned)) if (!_channel.TextureManager.CommitGraphicsBindings(_shaderSpecState) || (buffers.HasUnalignedStorageBuffers != hasUnaligned))
{ {
// Shader must be reloaded. _currentSpecState.SetHasUnalignedStorageBuffer(buffers.HasUnalignedStorageBuffers);
// Shader must be reloaded. _vtgWritesRtLayer should not change.
UpdateShaderState(); UpdateShaderState();
} }
@@ -351,6 +361,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_state.State.PatchVertices, _state.State.PatchVertices,
_state.State.TessOuterLevel.AsSpan(), _state.State.TessOuterLevel.AsSpan(),
_state.State.TessInnerLevel.AsSpan()); _state.State.TessInnerLevel.AsSpan());
_currentSpecState.SetTessellationMode(_state.State.TessMode);
} }
/// <summary> /// <summary>
@@ -611,6 +623,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_state.State.AlphaTestEnable, _state.State.AlphaTestEnable,
_state.State.AlphaTestRef, _state.State.AlphaTestRef,
_state.State.AlphaTestFunc); _state.State.AlphaTestFunc);
_currentSpecState.SetAlphaTest(
_state.State.AlphaTestEnable,
_state.State.AlphaTestRef,
_state.State.AlphaTestFunc);
} }
/// <summary> /// <summary>
@@ -710,6 +727,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_context.Renderer.Pipeline.SetDepthMode(GetDepthMode()); _context.Renderer.Pipeline.SetDepthMode(GetDepthMode());
_context.Renderer.Pipeline.SetViewports(viewports, disableTransform); _context.Renderer.Pipeline.SetViewports(viewports, disableTransform);
_currentSpecState.SetViewportTransformDisable(_state.State.ViewportTransformEnable == 0);
_currentSpecState.SetDepthMode(GetDepthMode() == DepthMode.MinusOneToOne);
} }
/// <summary> /// <summary>
@@ -847,6 +867,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_channel.TextureManager.SetGraphicsTexturePool(texturePool.Address.Pack(), texturePool.MaximumId); _channel.TextureManager.SetGraphicsTexturePool(texturePool.Address.Pack(), texturePool.MaximumId);
_channel.TextureManager.SetGraphicsTextureBufferIndex((int)_state.State.TextureBufferIndex); _channel.TextureManager.SetGraphicsTextureBufferIndex((int)_state.State.TextureBufferIndex);
_currentSpecState.SetPoolState(GetPoolState());
} }
/// <summary> /// <summary>
@@ -887,6 +909,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_pipeline.SetVertexAttribs(vertexAttribs); _pipeline.SetVertexAttribs(vertexAttribs);
_context.Renderer.Pipeline.SetVertexAttribs(vertexAttribs); _context.Renderer.Pipeline.SetVertexAttribs(vertexAttribs);
_currentSpecState.SetAttributeTypes(ref _state.State.VertexAttribState);
} }
/// <summary> /// <summary>
@@ -914,6 +937,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
Origin origin = (_state.State.PointCoordReplace & 4) == 0 ? Origin.LowerLeft : Origin.UpperLeft; Origin origin = (_state.State.PointCoordReplace & 4) == 0 ? Origin.LowerLeft : Origin.UpperLeft;
_context.Renderer.Pipeline.SetPointParameters(size, isProgramPointSize, enablePointSprite, origin); _context.Renderer.Pipeline.SetPointParameters(size, isProgramPointSize, enablePointSprite, origin);
_currentSpecState.SetProgramPointSizeEnable(isProgramPointSize);
_currentSpecState.SetPointSize(size);
} }
/// <summary> /// <summary>
@@ -1212,6 +1238,16 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
alphaToCoverageEnable, alphaToCoverageEnable,
_state.State.AlphaToCoverageDitherEnable, _state.State.AlphaToCoverageDitherEnable,
alphaToOneEnable)); alphaToOneEnable));
_currentSpecState.SetAlphaToCoverageEnable(alphaToCoverageEnable, _state.State.AlphaToCoverageDitherEnable);
}
/// <summary>
/// Updates the early z flag, based on guest state.
/// </summary>
private void UpdateEarlyZState()
{
_currentSpecState.SetEarlyZForce(_state.State.EarlyZForce);
} }
/// <summary> /// <summary>
@@ -1239,10 +1275,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
addressesSpan[index] = baseAddress + shader.Offset; addressesSpan[index] = baseAddress + shader.Offset;
} }
GpuChannelPoolState poolState = GetPoolState(); CachedShaderProgram gs = shaderCache.GetGraphicsShader(ref _state.State, ref _pipeline, _channel, ref _currentSpecState.GetPoolState(), ref _currentSpecState.GetGraphicsState(), addresses);
GpuChannelGraphicsState graphicsState = GetGraphicsState();
CachedShaderProgram gs = shaderCache.GetGraphicsShader(ref _state.State, ref _pipeline, _channel, poolState, graphicsState, addresses); // Consume the modified flag for spec state so that it isn't checked again.
_currentSpecState.SetShader(gs);
_shaderSpecState = gs.SpecializationState; _shaderSpecState = gs.SpecializationState;
@@ -1289,46 +1325,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
(int)_state.State.TextureBufferIndex); (int)_state.State.TextureBufferIndex);
} }
/// <summary>
/// Gets the current GPU channel state for shader creation or compatibility verification.
/// </summary>
/// <returns>Current GPU channel state</returns>
private GpuChannelGraphicsState GetGraphicsState()
{
ref var vertexAttribState = ref _state.State.VertexAttribState;
Array32<AttributeType> attributeTypes = new Array32<AttributeType>();
for (int location = 0; location < attributeTypes.Length; location++)
{
VertexAttribType type = vertexAttribState[location].UnpackType();
attributeTypes[location] = type switch
{
VertexAttribType.Sint => AttributeType.Sint,
VertexAttribType.Uint => AttributeType.Uint,
_ => AttributeType.Float
};
}
return new GpuChannelGraphicsState(
_state.State.EarlyZForce,
_drawState.Topology,
_state.State.TessMode,
(_state.State.MultisampleControl & 1) != 0,
_state.State.AlphaToCoverageDitherEnable,
_state.State.ViewportTransformEnable == 0,
GetDepthMode() == DepthMode.MinusOneToOne,
_state.State.VertexProgramPointSize,
_state.State.PointSize,
_state.State.AlphaTestEnable,
_state.State.AlphaTestFunc,
_state.State.AlphaTestRef,
ref attributeTypes,
_drawState.HasConstantBufferDrawParameters,
_channel.BufferManager.HasUnalignedStorageBuffers);
}
/// <summary> /// <summary>
/// Gets the depth mode that is currently being used (zero to one or minus one to one). /// Gets the depth mode that is currently being used (zero to one or minus one to one).
/// </summary> /// </summary>

View File

@@ -67,12 +67,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_i2mClass = new InlineToMemoryClass(context, channel, initializeState: false); _i2mClass = new InlineToMemoryClass(context, channel, initializeState: false);
var spec = new SpecializationStateUpdater();
var drawState = new DrawState(); var drawState = new DrawState();
_drawManager = new DrawManager(context, channel, _state, drawState); _drawManager = new DrawManager(context, channel, _state, drawState, spec);
_semaphoreUpdater = new SemaphoreUpdater(context, channel, _state); _semaphoreUpdater = new SemaphoreUpdater(context, channel, _state);
_cbUpdater = new ConstantBufferUpdater(channel, _state); _cbUpdater = new ConstantBufferUpdater(channel, _state);
_stateUpdater = new StateUpdater(context, channel, _state, drawState); _stateUpdater = new StateUpdater(context, channel, _state, drawState, spec);
// This defaults to "always", even without any register write. // This defaults to "always", even without any register write.
// Reads just return 0, regardless of what was set there. // Reads just return 0, regardless of what was set there.

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <summary> /// <summary>
/// Represents texture format information. /// Represents texture format information.
/// </summary> /// </summary>
struct FormatInfo readonly struct FormatInfo
{ {
/// <summary> /// <summary>
/// A default, generic RGBA8 texture format. /// A default, generic RGBA8 texture format.

View File

@@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// Texture binding information. /// Texture binding information.
/// This is used for textures that needs to be accessed from shaders. /// This is used for textures that needs to be accessed from shaders.
/// </summary> /// </summary>
struct TextureBindingInfo readonly struct TextureBindingInfo
{ {
/// <summary> /// <summary>
/// Shader sampler target type. /// Shader sampler target type.

View File

@@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary> /// </summary>
class TextureCache : IDisposable class TextureCache : IDisposable
{ {
private struct OverlapInfo private readonly struct OverlapInfo
{ {
public TextureViewCompatibility Compatibility { get; } public TextureViewCompatibility Compatibility { get; }
public int FirstLayer { get; } public int FirstLayer { get; }
@@ -1088,10 +1088,9 @@ namespace Ryujinx.Graphics.Gpu.Image
{ {
FormatInfo formatInfo = TextureCompatibility.ToHostCompatibleFormat(info, caps); FormatInfo formatInfo = TextureCompatibility.ToHostCompatibleFormat(info, caps);
if (info.Target == Target.TextureBuffer) if (info.Target == Target.TextureBuffer && !caps.SupportsSnormBufferTextureFormat)
{ {
// We assume that the host does not support signed normalized format // If the host does not support signed normalized formats, we use a signed integer format instead.
// (as is the case with OpenGL), so we just use a unsigned format.
// The shader will need the appropriate conversion code to compensate. // The shader will need the appropriate conversion code to compensate.
switch (formatInfo.Format) switch (formatInfo.Format)
{ {

View File

@@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <summary> /// <summary>
/// An overlapping texture group with a given view compatibility. /// An overlapping texture group with a given view compatibility.
/// </summary> /// </summary>
struct TextureIncompatibleOverlap readonly struct TextureIncompatibleOverlap
{ {
public readonly TextureGroup Group; public readonly TextureGroup Group;
public readonly TextureViewCompatibility Compatibility; public readonly TextureViewCompatibility Compatibility;

View File

@@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <summary> /// <summary>
/// Texture information. /// Texture information.
/// </summary> /// </summary>
struct TextureInfo readonly struct TextureInfo
{ {
/// <summary> /// <summary>
/// Address of the texture in GPU mapped memory. /// Address of the texture in GPU mapped memory.

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// <summary> /// <summary>
/// Memory range used for buffers. /// Memory range used for buffers.
/// </summary> /// </summary>
struct BufferBounds readonly struct BufferBounds
{ {
/// <summary> /// <summary>
/// Region virtual address. /// Region virtual address.

View File

@@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// <summary> /// <summary>
/// A buffer binding to apply to a buffer texture. /// A buffer binding to apply to a buffer texture.
/// </summary> /// </summary>
struct BufferTextureBinding readonly struct BufferTextureBinding
{ {
/// <summary> /// <summary>
/// Shader stage accessing the texture. /// Shader stage accessing the texture.

View File

@@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// </summary> /// </summary>
class CounterCache class CounterCache
{ {
private struct CounterEntry private readonly struct CounterEntry
{ {
public ulong Address { get; } public ulong Address { get; }
public ICounterEvent Event { get; } public ICounterEvent Event { get; }

View File

@@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
/// <summary> /// <summary>
/// Represents an operation to perform on the <see cref="_fileWriterWorkerQueue"/>. /// Represents an operation to perform on the <see cref="_fileWriterWorkerQueue"/>.
/// </summary> /// </summary>
private struct CacheFileOperationTask private readonly struct CacheFileOperationTask
{ {
/// <summary> /// <summary>
/// The type of operation to perform. /// The type of operation to perform.
@@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
/// <summary> /// <summary>
/// Background shader cache write information. /// Background shader cache write information.
/// </summary> /// </summary>
private struct AddShaderData private readonly struct AddShaderData
{ {
/// <summary> /// <summary>
/// Cached shader program. /// Cached shader program.

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2; private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
private const uint CodeGenVersion = 3943; private const uint CodeGenVersion = 4011;
private const string SharedTocFileName = "shared.toc"; private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data"; private const string SharedDataFileName = "shared.data";

View File

@@ -3,7 +3,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
/// <summary> /// <summary>
/// Guest shader code and constant buffer data accessed by the shader. /// Guest shader code and constant buffer data accessed by the shader.
/// </summary> /// </summary>
struct GuestCodeAndCbData readonly struct GuestCodeAndCbData
{ {
/// <summary> /// <summary>
/// Maxwell binary shader code. /// Maxwell binary shader code.

View File

@@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
/// <summary> /// <summary>
/// Program validation entry. /// Program validation entry.
/// </summary> /// </summary>
private struct ProgramEntry private readonly struct ProgramEntry
{ {
/// <summary> /// <summary>
/// Cached shader program. /// Cached shader program.
@@ -90,7 +90,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
/// <summary> /// <summary>
/// Translated shader compilation entry. /// Translated shader compilation entry.
/// </summary> /// </summary>
private struct ProgramCompilation private readonly struct ProgramCompilation
{ {
/// <summary> /// <summary>
/// Translated shader stages. /// Translated shader stages.
@@ -143,7 +143,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
/// <summary> /// <summary>
/// Program translation entry. /// Program translation entry.
/// </summary> /// </summary>
private struct AsyncProgramTranslation private readonly struct AsyncProgramTranslation
{ {
/// <summary> /// <summary>
/// Guest code for each active stage. /// Guest code for each active stage.

View File

@@ -134,6 +134,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
public bool QueryHostSupportsShaderBallot() => _context.Capabilities.SupportsShaderBallot; public bool QueryHostSupportsShaderBallot() => _context.Capabilities.SupportsShaderBallot;
public bool QueryHostSupportsSnormBufferTextureFormat() => _context.Capabilities.SupportsSnormBufferTextureFormat;
public bool QueryHostSupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod; public bool QueryHostSupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod;
public bool QueryHostSupportsViewportIndex() => _context.Capabilities.SupportsViewportIndex; public bool QueryHostSupportsViewportIndex() => _context.Capabilities.SupportsViewportIndex;

View File

@@ -3,7 +3,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <summary> /// <summary>
/// State used by the <see cref="GpuAccessor"/>. /// State used by the <see cref="GpuAccessor"/>.
/// </summary> /// </summary>
struct GpuChannelComputeState readonly struct GpuChannelComputeState
{ {
// New fields should be added to the end of the struct to keep disk shader cache compatibility. // New fields should be added to the end of the struct to keep disk shader cache compatibility.

View File

@@ -15,62 +15,62 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <summary> /// <summary>
/// Early Z force enable. /// Early Z force enable.
/// </summary> /// </summary>
public readonly bool EarlyZForce; public bool EarlyZForce;
/// <summary> /// <summary>
/// Primitive topology of current draw. /// Primitive topology of current draw.
/// </summary> /// </summary>
public readonly PrimitiveTopology Topology; public PrimitiveTopology Topology;
/// <summary> /// <summary>
/// Tessellation mode. /// Tessellation mode.
/// </summary> /// </summary>
public readonly TessMode TessellationMode; public TessMode TessellationMode;
/// <summary> /// <summary>
/// Indicates whether alpha-to-coverage is enabled. /// Indicates whether alpha-to-coverage is enabled.
/// </summary> /// </summary>
public readonly bool AlphaToCoverageEnable; public bool AlphaToCoverageEnable;
/// <summary> /// <summary>
/// Indicates whether alpha-to-coverage dithering is enabled. /// Indicates whether alpha-to-coverage dithering is enabled.
/// </summary> /// </summary>
public readonly bool AlphaToCoverageDitherEnable; public bool AlphaToCoverageDitherEnable;
/// <summary> /// <summary>
/// Indicates whether the viewport transform is disabled. /// Indicates whether the viewport transform is disabled.
/// </summary> /// </summary>
public readonly bool ViewportTransformDisable; public bool ViewportTransformDisable;
/// <summary> /// <summary>
/// Depth mode zero to one or minus one to one. /// Depth mode zero to one or minus one to one.
/// </summary> /// </summary>
public readonly bool DepthMode; public bool DepthMode;
/// <summary> /// <summary>
/// Indicates if the point size is set on the shader or is fixed. /// Indicates if the point size is set on the shader or is fixed.
/// </summary> /// </summary>
public readonly bool ProgramPointSizeEnable; public bool ProgramPointSizeEnable;
/// <summary> /// <summary>
/// Point size used if <see cref="ProgramPointSizeEnable" /> is false. /// Point size used if <see cref="ProgramPointSizeEnable" /> is false.
/// </summary> /// </summary>
public readonly float PointSize; public float PointSize;
/// <summary> /// <summary>
/// Indicates whether alpha test is enabled. /// Indicates whether alpha test is enabled.
/// </summary> /// </summary>
public readonly bool AlphaTestEnable; public bool AlphaTestEnable;
/// <summary> /// <summary>
/// When alpha test is enabled, indicates the comparison that decides if the fragment should be discarded. /// When alpha test is enabled, indicates the comparison that decides if the fragment should be discarded.
/// </summary> /// </summary>
public readonly CompareOp AlphaTestCompare; public CompareOp AlphaTestCompare;
/// <summary> /// <summary>
/// When alpha test is enabled, indicates the value to compare with the fragment output alpha. /// When alpha test is enabled, indicates the value to compare with the fragment output alpha.
/// </summary> /// </summary>
public readonly float AlphaTestReference; public float AlphaTestReference;
/// <summary> /// <summary>
/// Type of the vertex attributes consumed by the shader. /// Type of the vertex attributes consumed by the shader.
@@ -80,12 +80,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <summary> /// <summary>
/// Indicates that the draw is writing the base vertex, base instance and draw index to Constant Buffer 0. /// Indicates that the draw is writing the base vertex, base instance and draw index to Constant Buffer 0.
/// </summary> /// </summary>
public readonly bool HasConstantBufferDrawParameters; public bool HasConstantBufferDrawParameters;
/// <summary> /// <summary>
/// Indicates that any storage buffer use is unaligned. /// Indicates that any storage buffer use is unaligned.
/// </summary> /// </summary>
public readonly bool HasUnalignedStorageBuffer; public bool HasUnalignedStorageBuffer;
/// <summary> /// <summary>
/// Creates a new GPU graphics state. /// Creates a new GPU graphics state.

View File

@@ -1,9 +1,11 @@
using System;
namespace Ryujinx.Graphics.Gpu.Shader namespace Ryujinx.Graphics.Gpu.Shader
{ {
/// <summary> /// <summary>
/// State used by the <see cref="GpuAccessor"/>. /// State used by the <see cref="GpuAccessor"/>.
/// </summary> /// </summary>
struct GpuChannelPoolState readonly struct GpuChannelPoolState : IEquatable<GpuChannelPoolState>
{ {
/// <summary> /// <summary>
/// GPU virtual address of the texture pool. /// GPU virtual address of the texture pool.
@@ -32,5 +34,17 @@ namespace Ryujinx.Graphics.Gpu.Shader
TexturePoolMaximumId = texturePoolMaximumId; TexturePoolMaximumId = texturePoolMaximumId;
TextureBufferIndex = textureBufferIndex; TextureBufferIndex = textureBufferIndex;
} }
/// <summary>
/// Check if the pool states are equal.
/// </summary>
/// <param name="other">Pool state to compare with</param>
/// <returns>True if they are equal, false otherwise</returns>
public bool Equals(GpuChannelPoolState other)
{
return TexturePoolGpuVa == other.TexturePoolGpuVa &&
TexturePoolMaximumId == other.TexturePoolMaximumId &&
TextureBufferIndex == other.TextureBufferIndex;
}
} }
} }

View File

@@ -13,7 +13,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.HashTable
/// <summary> /// <summary>
/// Entry for a given data size. /// Entry for a given data size.
/// </summary> /// </summary>
private struct SizeEntry private readonly struct SizeEntry
{ {
/// <summary> /// <summary>
/// Size for the data that will be stored on the hash table on this entry. /// Size for the data that will be stored on the hash table on this entry.

Some files were not shown because too many files have changed in this diff Show More