Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
d6bc0de785 | |||
9f26fd3600 | |||
88df636c87 | |||
7ccff037e8 | |||
a745913329 | |||
e6700b314f | |||
e2cfe6fe44 |
@ -1,6 +1,7 @@
|
|||||||
using Avalonia.Data;
|
using Avalonia.Data.Core;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using Avalonia.Markup.Xaml.MarkupExtensions;
|
using Avalonia.Markup.Xaml.MarkupExtensions;
|
||||||
|
using Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Common.Locale
|
namespace Ryujinx.Ava.Common.Locale
|
||||||
@ -18,11 +19,20 @@ namespace Ryujinx.Ava.Common.Locale
|
|||||||
{
|
{
|
||||||
LocaleKeys keyToUse = Key;
|
LocaleKeys keyToUse = Key;
|
||||||
|
|
||||||
ReflectionBindingExtension binding = new($"[{keyToUse}]")
|
var builder = new CompiledBindingPathBuilder();
|
||||||
{
|
|
||||||
Mode = BindingMode.OneWay,
|
builder.SetRawSource(LocaleManager.Instance)
|
||||||
Source = LocaleManager.Instance,
|
.Property(new ClrPropertyInfo("Item",
|
||||||
};
|
obj => (LocaleManager.Instance[keyToUse]),
|
||||||
|
null,
|
||||||
|
typeof(string)), (weakRef, iPropInfo) =>
|
||||||
|
{
|
||||||
|
return PropertyInfoAccessorFactory.CreateInpcPropertyAccessor(weakRef, iPropInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
var path = builder.Build();
|
||||||
|
|
||||||
|
var binding = new CompiledBindingExtension(path);
|
||||||
|
|
||||||
return binding.ProvideValue(serviceProvider);
|
return binding.ProvideValue(serviceProvider);
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,11 @@
|
|||||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
Title="{locale:Locale ErrorWindowTitle}"
|
Title="{locale:Locale ErrorWindowTitle}"
|
||||||
|
xmlns:views="using:Ryujinx.Ava.UI.Applet"
|
||||||
Width="450"
|
Width="450"
|
||||||
Height="340"
|
Height="340"
|
||||||
CanResize="False"
|
CanResize="False"
|
||||||
|
x:DataType="views:ErrorAppletWindow"
|
||||||
SizeToContent="Height"
|
SizeToContent="Height"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Focusable="True">
|
Focusable="True">
|
||||||
@ -38,7 +40,7 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="10"
|
Margin="10"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Text="{ReflectionBinding Message}"
|
Text="{Binding Message}"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Name="ButtonStack"
|
Name="ButtonStack"
|
||||||
@ -49,4 +51,4 @@
|
|||||||
Orientation="Horizontal"
|
Orientation="Horizontal"
|
||||||
Spacing="10" />
|
Spacing="10" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
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"
|
||||||
|
xmlns:views="using:Ryujinx.Ava.UI.Controls"
|
||||||
Width="400"
|
Width="400"
|
||||||
|
x:DataType="views:SwkbdAppletDialog"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Focusable="True">
|
Focusable="True">
|
||||||
<Grid
|
<Grid
|
||||||
@ -34,13 +36,13 @@
|
|||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Text="{ReflectionBinding MainText}"
|
Text="{Binding MainText}"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Text="{ReflectionBinding SecondaryText}"
|
Text="{Binding SecondaryText}"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
<TextBox
|
<TextBox
|
||||||
Name="Input"
|
Name="Input"
|
||||||
@ -50,7 +52,7 @@
|
|||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Focusable="True"
|
Focusable="True"
|
||||||
KeyUp="Message_KeyUp"
|
KeyUp="Message_KeyUp"
|
||||||
Text="{ReflectionBinding Message}"
|
Text="{Binding Message}"
|
||||||
TextInput="Message_TextInput"
|
TextInput="Message_TextInput"
|
||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
UseFloatingWatermark="True" />
|
UseFloatingWatermark="True" />
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
<Setter Property="CornerRadius" Value="4" />
|
<Setter Property="CornerRadius" Value="4" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="ListBoxItem:selected /template/ Rectangle#SelectionIndicator">
|
<Style Selector="ListBoxItem:selected /template/ Rectangle#SelectionIndicator">
|
||||||
<Setter Property="MinHeight" Value="{ReflectionBinding $parent[UserControl].DataContext.GridItemSelectorSize}" />
|
<Setter Property="MinHeight" Value="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).GridItemSelectorSize}" />
|
||||||
</Style>
|
</Style>
|
||||||
</ListBox.Styles>
|
</ListBox.Styles>
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
@ -56,10 +56,10 @@
|
|||||||
Margin="10"
|
Margin="10"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Classes.huge="{ReflectionBinding $parent[UserControl].DataContext.IsGridHuge}"
|
Classes.huge="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridHuge}"
|
||||||
Classes.large="{ReflectionBinding $parent[UserControl].DataContext.IsGridLarge}"
|
Classes.large="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridLarge}"
|
||||||
Classes.normal="{ReflectionBinding $parent[UserControl].DataContext.IsGridMedium}"
|
Classes.normal="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridMedium}"
|
||||||
Classes.small="{ReflectionBinding $parent[UserControl].DataContext.IsGridSmall}"
|
Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}"
|
||||||
ClipToBounds="True"
|
ClipToBounds="True"
|
||||||
CornerRadius="4">
|
CornerRadius="4">
|
||||||
<Grid>
|
<Grid>
|
||||||
@ -78,7 +78,7 @@
|
|||||||
Margin="0,10,0,0"
|
Margin="0,10,0,0"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
IsVisible="{ReflectionBinding $parent[UserControl].DataContext.ShowNames}">
|
IsVisible="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).ShowNames}">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
@ -101,4 +101,4 @@
|
|||||||
</ListBox.ItemTemplate>
|
</ListBox.ItemTemplate>
|
||||||
</ListBox>
|
</ListBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
</ListBox.ItemsPanel>
|
</ListBox.ItemsPanel>
|
||||||
<ListBox.Styles>
|
<ListBox.Styles>
|
||||||
<Style Selector="ListBoxItem:selected /template/ Rectangle#SelectionIndicator">
|
<Style Selector="ListBoxItem:selected /template/ Rectangle#SelectionIndicator">
|
||||||
<Setter Property="MinHeight" Value="{ReflectionBinding $parent[UserControl].DataContext.ListItemSelectorSize}" />
|
<Setter Property="MinHeight" Value="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).ListItemSelectorSize}" />
|
||||||
</Style>
|
</Style>
|
||||||
</ListBox.Styles>
|
</ListBox.Styles>
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
@ -67,10 +67,10 @@
|
|||||||
Grid.RowSpan="3"
|
Grid.RowSpan="3"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Margin="0"
|
Margin="0"
|
||||||
Classes.huge="{ReflectionBinding $parent[UserControl].DataContext.IsGridHuge}"
|
Classes.huge="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridHuge}"
|
||||||
Classes.large="{ReflectionBinding $parent[UserControl].DataContext.IsGridLarge}"
|
Classes.large="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridLarge}"
|
||||||
Classes.normal="{ReflectionBinding $parent[UserControl].DataContext.IsGridMedium}"
|
Classes.normal="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridMedium}"
|
||||||
Classes.small="{ReflectionBinding $parent[UserControl].DataContext.IsGridSmall}"
|
Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}"
|
||||||
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
|
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
|
||||||
<Border
|
<Border
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
@ -157,4 +157,4 @@
|
|||||||
</ListBox.ItemTemplate>
|
</ListBox.ItemTemplate>
|
||||||
</ListBox>
|
</ListBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
Height="500"
|
Height="500"
|
||||||
MinWidth="500"
|
MinWidth="500"
|
||||||
MinHeight="500"
|
MinHeight="500"
|
||||||
|
x:DataType="window:CheatWindow"
|
||||||
WindowStartupLocation="CenterOwner"
|
WindowStartupLocation="CenterOwner"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Focusable="True">
|
Focusable="True">
|
||||||
@ -40,7 +41,7 @@
|
|||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
LineHeight="18"
|
LineHeight="18"
|
||||||
Text="{ReflectionBinding Heading}"
|
Text="{Binding Heading}"
|
||||||
TextAlignment="Center"
|
TextAlignment="Center"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@ -61,7 +62,7 @@
|
|||||||
MinWidth="160"
|
MinWidth="160"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{ReflectionBinding BuildId}"
|
Text="{Binding BuildId}"
|
||||||
IsReadOnly="True" />
|
IsReadOnly="True" />
|
||||||
<Border
|
<Border
|
||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
@ -77,7 +78,7 @@
|
|||||||
MinHeight="300"
|
MinHeight="300"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
ItemsSource="{ReflectionBinding LoadedCheats}">
|
ItemsSource="{Binding LoadedCheats}">
|
||||||
<TreeView.Styles>
|
<TreeView.Styles>
|
||||||
<Styles>
|
<Styles>
|
||||||
<Style Selector="TreeViewItem:empty /template/ ItemsPresenter">
|
<Style Selector="TreeViewItem:empty /template/ ItemsPresenter">
|
||||||
@ -120,18 +121,18 @@
|
|||||||
Name="SaveButton"
|
Name="SaveButton"
|
||||||
MinWidth="90"
|
MinWidth="90"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{ReflectionBinding Save}"
|
Command="{Binding Save}"
|
||||||
IsVisible="{ReflectionBinding !NoCheatsFound}">
|
IsVisible="{Binding !NoCheatsFound}">
|
||||||
<TextBlock Text="{locale:Locale SettingsButtonSave}" />
|
<TextBlock Text="{locale:Locale SettingsButtonSave}" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
Name="CancelButton"
|
Name="CancelButton"
|
||||||
MinWidth="90"
|
MinWidth="90"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{ReflectionBinding Close}">
|
Command="{Binding Close}">
|
||||||
<TextBlock Text="{locale:Locale InputDialogCancel}" />
|
<TextBlock Text="{locale:Locale InputDialogCancel}" />
|
||||||
</Button>
|
</Button>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</window:StyleableWindow>
|
</window:StyleableWindow>
|
||||||
|
@ -39,14 +39,14 @@
|
|||||||
Name="EnableAllButton"
|
Name="EnableAllButton"
|
||||||
MinWidth="90"
|
MinWidth="90"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{ReflectionBinding EnableAll}">
|
Command="{Binding EnableAll}">
|
||||||
<TextBlock Text="{locale:Locale DlcManagerEnableAllButton}" />
|
<TextBlock Text="{locale:Locale DlcManagerEnableAllButton}" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
Name="DisableAllButton"
|
Name="DisableAllButton"
|
||||||
MinWidth="90"
|
MinWidth="90"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{ReflectionBinding DisableAll}">
|
Command="{Binding DisableAll}">
|
||||||
<TextBlock Text="{locale:Locale DlcManagerDisableAllButton}" />
|
<TextBlock Text="{locale:Locale DlcManagerDisableAllButton}" />
|
||||||
</Button>
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@ -157,14 +157,14 @@
|
|||||||
Name="AddButton"
|
Name="AddButton"
|
||||||
MinWidth="90"
|
MinWidth="90"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{ReflectionBinding Add}">
|
Command="{Binding Add}">
|
||||||
<TextBlock Text="{locale:Locale SettingsTabGeneralAdd}" />
|
<TextBlock Text="{locale:Locale SettingsTabGeneralAdd}" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
Name="RemoveAllButton"
|
Name="RemoveAllButton"
|
||||||
MinWidth="90"
|
MinWidth="90"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Command="{ReflectionBinding RemoveAll}">
|
Command="{Binding RemoveAll}">
|
||||||
<TextBlock Text="{locale:Locale DlcManagerRemoveAllButton}" />
|
<TextBlock Text="{locale:Locale DlcManagerRemoveAllButton}" />
|
||||||
</Button>
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@ -189,4 +189,4 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Panel>
|
</Panel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
@ -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 = 5551;
|
private const uint CodeGenVersion = 5682;
|
||||||
|
|
||||||
private const string SharedTocFileName = "shared.toc";
|
private const string SharedTocFileName = "shared.toc";
|
||||||
private const string SharedDataFileName = "shared.data";
|
private const string SharedDataFileName = "shared.data";
|
||||||
|
@ -89,6 +89,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
context.AddCapability(Capability.DrawParameters);
|
context.AddCapability(Capability.DrawParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.Definitions.Stage != ShaderStage.Fragment &&
|
||||||
|
context.Definitions.Stage != ShaderStage.Geometry &&
|
||||||
|
context.Definitions.Stage != ShaderStage.Compute &&
|
||||||
|
(context.Info.IoDefinitions.Contains(new IoDefinition(StorageKind.Output, IoVariable.Layer)) ||
|
||||||
|
context.Info.IoDefinitions.Contains(new IoDefinition(StorageKind.Output, IoVariable.ViewportIndex))))
|
||||||
|
{
|
||||||
|
context.AddExtension("SPV_EXT_shader_viewport_index_layer");
|
||||||
|
context.AddCapability(Capability.ShaderViewportIndexLayerEXT);
|
||||||
|
}
|
||||||
|
|
||||||
if (context.Info.IoDefinitions.Contains(new IoDefinition(StorageKind.Output, IoVariable.ViewportMask)))
|
if (context.Info.IoDefinitions.Contains(new IoDefinition(StorageKind.Output, IoVariable.ViewportMask)))
|
||||||
{
|
{
|
||||||
context.AddExtension("SPV_NV_viewport_array2");
|
context.AddExtension("SPV_NV_viewport_array2");
|
||||||
@ -277,14 +287,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
localSizeZ);
|
localSizeZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.Definitions.Stage != ShaderStage.Fragment &&
|
|
||||||
context.Definitions.Stage != ShaderStage.Geometry &&
|
|
||||||
context.Definitions.Stage != ShaderStage.Compute &&
|
|
||||||
context.Info.IoDefinitions.Contains(new IoDefinition(StorageKind.Output, IoVariable.Layer)))
|
|
||||||
{
|
|
||||||
context.AddCapability(Capability.ShaderLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context.Definitions.TransformFeedbackEnabled && context.Definitions.LastInVertexPipeline)
|
if (context.Definitions.TransformFeedbackEnabled && context.Definitions.LastInVertexPipeline)
|
||||||
{
|
{
|
||||||
context.AddExecutionMode(spvFunc, ExecutionMode.Xfb);
|
context.AddExecutionMode(spvFunc, ExecutionMode.Xfb);
|
||||||
|
@ -1126,7 +1126,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||||||
// so we want to get the byte offset back, since each one of those word
|
// so we want to get the byte offset back, since each one of those word
|
||||||
// offsets are a new "local variable" which will not match.
|
// offsets are a new "local variable" which will not match.
|
||||||
|
|
||||||
if (operation.GetSource(0).AsgOp is Operation shiftRightOp &&
|
if (operation.GetSource(1).AsgOp is Operation shiftRightOp &&
|
||||||
shiftRightOp.Inst == Instruction.ShiftRightU32 &&
|
shiftRightOp.Inst == Instruction.ShiftRightU32 &&
|
||||||
shiftRightOp.GetSource(1).Type == OperandType.Constant &&
|
shiftRightOp.GetSource(1).Type == OperandType.Constant &&
|
||||||
shiftRightOp.GetSource(1).Value == 2)
|
shiftRightOp.GetSource(1).Value == 2)
|
||||||
@ -1158,9 +1158,11 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||||||
|
|
||||||
private static bool TryGetLocalMemoryOffset(Operation operation, out int constOffset)
|
private static bool TryGetLocalMemoryOffset(Operation operation, out int constOffset)
|
||||||
{
|
{
|
||||||
if (operation.GetSource(0).Type == OperandType.Constant)
|
Operand offset = operation.GetSource(1);
|
||||||
|
|
||||||
|
if (offset.Type == OperandType.Constant)
|
||||||
{
|
{
|
||||||
constOffset = operation.GetSource(0).Value;
|
constOffset = offset.Value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,6 +576,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
int outputAttributesMask = AttributeUsage.UsedOutputAttributes;
|
int outputAttributesMask = AttributeUsage.UsedOutputAttributes;
|
||||||
int layerOutputAttr = LayerOutputAttribute;
|
int layerOutputAttr = LayerOutputAttribute;
|
||||||
|
|
||||||
|
if (LayerOutputWritten)
|
||||||
|
{
|
||||||
|
outputAttributesMask |= 1 << ((layerOutputAttr - AttributeConsts.UserAttributeBase) / 16);
|
||||||
|
}
|
||||||
|
|
||||||
OutputTopology outputTopology;
|
OutputTopology outputTopology;
|
||||||
int maxOutputVertices;
|
int maxOutputVertices;
|
||||||
|
|
||||||
|
@ -257,14 +257,22 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (realIndex != -1)
|
if (realIndex != -1)
|
||||||
{
|
{
|
||||||
_colors[realIndex].Storage?.InsertReadToWriteBarrier(cbs, AccessFlags.ColorAttachmentWriteBit, PipelineStageFlags.ColorAttachmentOutputBit);
|
_colors[realIndex].Storage?.InsertReadToWriteBarrier(
|
||||||
|
cbs,
|
||||||
|
AccessFlags.ColorAttachmentWriteBit,
|
||||||
|
PipelineStageFlags.ColorAttachmentOutputBit,
|
||||||
|
insideRenderPass: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InsertClearBarrierDS(CommandBufferScoped cbs)
|
public void InsertClearBarrierDS(CommandBufferScoped cbs)
|
||||||
{
|
{
|
||||||
_depthStencil?.Storage?.InsertReadToWriteBarrier(cbs, AccessFlags.DepthStencilAttachmentWriteBit, PipelineStageFlags.LateFragmentTestsBit);
|
_depthStencil?.Storage?.InsertReadToWriteBarrier(
|
||||||
|
cbs,
|
||||||
|
AccessFlags.DepthStencilAttachmentWriteBit,
|
||||||
|
PipelineStageFlags.LateFragmentTestsBit,
|
||||||
|
insideRenderPass: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
public readonly bool SupportsPreciseOcclusionQueries;
|
public readonly bool SupportsPreciseOcclusionQueries;
|
||||||
public readonly bool SupportsPipelineStatisticsQuery;
|
public readonly bool SupportsPipelineStatisticsQuery;
|
||||||
public readonly bool SupportsGeometryShader;
|
public readonly bool SupportsGeometryShader;
|
||||||
|
public readonly bool SupportsTessellationShader;
|
||||||
public readonly bool SupportsViewportArray2;
|
public readonly bool SupportsViewportArray2;
|
||||||
public readonly bool SupportsHostImportedMemory;
|
public readonly bool SupportsHostImportedMemory;
|
||||||
public readonly bool SupportsDepthClipControl;
|
public readonly bool SupportsDepthClipControl;
|
||||||
@ -77,6 +78,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
bool supportsPreciseOcclusionQueries,
|
bool supportsPreciseOcclusionQueries,
|
||||||
bool supportsPipelineStatisticsQuery,
|
bool supportsPipelineStatisticsQuery,
|
||||||
bool supportsGeometryShader,
|
bool supportsGeometryShader,
|
||||||
|
bool supportsTessellationShader,
|
||||||
bool supportsViewportArray2,
|
bool supportsViewportArray2,
|
||||||
bool supportsHostImportedMemory,
|
bool supportsHostImportedMemory,
|
||||||
bool supportsDepthClipControl,
|
bool supportsDepthClipControl,
|
||||||
@ -112,6 +114,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
SupportsPreciseOcclusionQueries = supportsPreciseOcclusionQueries;
|
SupportsPreciseOcclusionQueries = supportsPreciseOcclusionQueries;
|
||||||
SupportsPipelineStatisticsQuery = supportsPipelineStatisticsQuery;
|
SupportsPipelineStatisticsQuery = supportsPipelineStatisticsQuery;
|
||||||
SupportsGeometryShader = supportsGeometryShader;
|
SupportsGeometryShader = supportsGeometryShader;
|
||||||
|
SupportsTessellationShader = supportsTessellationShader;
|
||||||
SupportsViewportArray2 = supportsViewportArray2;
|
SupportsViewportArray2 = supportsViewportArray2;
|
||||||
SupportsHostImportedMemory = supportsHostImportedMemory;
|
SupportsHostImportedMemory = supportsHostImportedMemory;
|
||||||
SupportsDepthClipControl = supportsDepthClipControl;
|
SupportsDepthClipControl = supportsDepthClipControl;
|
||||||
|
@ -149,10 +149,22 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PipelineStageFlags pipelineStageFlags = PipelineStageFlags.VertexShaderBit | PipelineStageFlags.FragmentShaderBit;
|
||||||
|
|
||||||
|
if (Gd.Capabilities.SupportsGeometryShader)
|
||||||
|
{
|
||||||
|
pipelineStageFlags |= PipelineStageFlags.GeometryShaderBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Gd.Capabilities.SupportsTessellationShader)
|
||||||
|
{
|
||||||
|
pipelineStageFlags |= PipelineStageFlags.TessellationControlShaderBit | PipelineStageFlags.TessellationEvaluationShaderBit;
|
||||||
|
}
|
||||||
|
|
||||||
Gd.Api.CmdPipelineBarrier(
|
Gd.Api.CmdPipelineBarrier(
|
||||||
CommandBuffer,
|
CommandBuffer,
|
||||||
PipelineStageFlags.FragmentShaderBit,
|
pipelineStageFlags,
|
||||||
PipelineStageFlags.FragmentShaderBit,
|
pipelineStageFlags,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
memoryBarrier,
|
memoryBarrier,
|
||||||
|
@ -9,8 +9,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
static class PipelineConverter
|
static class PipelineConverter
|
||||||
{
|
{
|
||||||
private const AccessFlags SubpassSrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit | AccessFlags.ColorAttachmentWriteBit;
|
private const AccessFlags SubpassAccessMask =
|
||||||
private const AccessFlags SubpassDstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit | AccessFlags.ShaderReadBit;
|
AccessFlags.MemoryReadBit |
|
||||||
|
AccessFlags.MemoryWriteBit |
|
||||||
|
AccessFlags.ShaderReadBit |
|
||||||
|
AccessFlags.ColorAttachmentWriteBit |
|
||||||
|
AccessFlags.DepthStencilAttachmentWriteBit;
|
||||||
|
|
||||||
public static unsafe DisposableRenderPass ToRenderPass(this ProgramPipelineState state, VulkanRenderer gd, Device device)
|
public static unsafe DisposableRenderPass ToRenderPass(this ProgramPipelineState state, VulkanRenderer gd, Device device)
|
||||||
{
|
{
|
||||||
@ -132,8 +136,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
0,
|
0,
|
||||||
PipelineStageFlags.AllGraphicsBit,
|
PipelineStageFlags.AllGraphicsBit,
|
||||||
PipelineStageFlags.AllGraphicsBit,
|
PipelineStageFlags.AllGraphicsBit,
|
||||||
SubpassSrcAccessMask,
|
SubpassAccessMask,
|
||||||
SubpassDstAccessMask,
|
SubpassAccessMask,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,8 +150,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
0,
|
0,
|
||||||
PipelineStageFlags.AllGraphicsBit,
|
PipelineStageFlags.AllGraphicsBit,
|
||||||
PipelineStageFlags.AllGraphicsBit,
|
PipelineStageFlags.AllGraphicsBit,
|
||||||
SubpassSrcAccessMask,
|
SubpassAccessMask,
|
||||||
SubpassDstAccessMask,
|
SubpassAccessMask,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +146,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private void RecordScissor(Vk api, CommandBuffer commandBuffer)
|
private void RecordScissor(Vk api, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
api.CmdSetScissor(commandBuffer, 0, (uint)ScissorsCount, _scissors.AsSpan());
|
if (ScissorsCount != 0)
|
||||||
|
{
|
||||||
|
api.CmdSetScissor(commandBuffer, 0, (uint)ScissorsCount, _scissors.AsSpan());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly void RecordStencilMasks(Vk api, CommandBuffer commandBuffer)
|
private readonly void RecordStencilMasks(Vk api, CommandBuffer commandBuffer)
|
||||||
|
@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
var sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
|
var sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
|
||||||
|
|
||||||
var usage = GetImageUsage(info.Format, info.Target, gd.Capabilities.SupportsShaderStorageImageMultisample, forceStorage: true);
|
var usage = GetImageUsage(info.Format, info.Target, gd.Capabilities.SupportsShaderStorageImageMultisample);
|
||||||
|
|
||||||
var flags = ImageCreateFlags.CreateMutableFormatBit;
|
var flags = ImageCreateFlags.CreateMutableFormatBit;
|
||||||
|
|
||||||
@ -291,7 +291,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImageUsageFlags GetImageUsage(Format format, Target target, bool supportsMsStorage, bool forceStorage = false)
|
public static ImageUsageFlags GetImageUsage(Format format, Target target, bool supportsMsStorage)
|
||||||
{
|
{
|
||||||
var usage = DefaultUsageFlags;
|
var usage = DefaultUsageFlags;
|
||||||
|
|
||||||
@ -304,7 +304,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
usage |= ImageUsageFlags.ColorAttachmentBit;
|
usage |= ImageUsageFlags.ColorAttachmentBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((forceStorage && !format.IsDepthOrStencil()) || format.IsImageCompatible()) && (supportsMsStorage || !target.IsMultisample()))
|
if (format.IsImageCompatible() && (supportsMsStorage || !target.IsMultisample()))
|
||||||
{
|
{
|
||||||
usage |= ImageUsageFlags.StorageBit;
|
usage |= ImageUsageFlags.StorageBit;
|
||||||
}
|
}
|
||||||
@ -440,25 +440,27 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_lastModificationStage = stage;
|
_lastModificationStage = stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InsertReadToWriteBarrier(CommandBufferScoped cbs, AccessFlags dstAccessFlags, PipelineStageFlags dstStageFlags)
|
public void InsertReadToWriteBarrier(CommandBufferScoped cbs, AccessFlags dstAccessFlags, PipelineStageFlags dstStageFlags, bool insideRenderPass)
|
||||||
{
|
{
|
||||||
if (_lastReadAccess != AccessFlags.None)
|
var lastReadStage = _lastReadStage;
|
||||||
{
|
|
||||||
ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags();
|
|
||||||
|
|
||||||
TextureView.InsertImageBarrier(
|
if (insideRenderPass)
|
||||||
|
{
|
||||||
|
// We can't have barrier from compute inside a render pass,
|
||||||
|
// as it is invalid to specify compute in the subpass dependency stage mask.
|
||||||
|
|
||||||
|
lastReadStage &= ~PipelineStageFlags.ComputeShaderBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastReadStage != PipelineStageFlags.None)
|
||||||
|
{
|
||||||
|
TextureView.InsertMemoryBarrier(
|
||||||
_gd.Api,
|
_gd.Api,
|
||||||
cbs.CommandBuffer,
|
cbs.CommandBuffer,
|
||||||
_imageAuto.Get(cbs).Value,
|
|
||||||
_lastReadAccess,
|
_lastReadAccess,
|
||||||
dstAccessFlags,
|
dstAccessFlags,
|
||||||
_lastReadStage,
|
lastReadStage,
|
||||||
dstStageFlags,
|
dstStageFlags);
|
||||||
aspectFlags,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
_info.GetLayers(),
|
|
||||||
_info.Levels);
|
|
||||||
|
|
||||||
_lastReadAccess = AccessFlags.None;
|
_lastReadAccess = AccessFlags.None;
|
||||||
_lastReadStage = PipelineStageFlags.None;
|
_lastReadStage = PipelineStageFlags.None;
|
||||||
@ -472,21 +474,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (_lastModificationAccess != AccessFlags.None)
|
if (_lastModificationAccess != AccessFlags.None)
|
||||||
{
|
{
|
||||||
ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags();
|
TextureView.InsertMemoryBarrier(
|
||||||
|
|
||||||
TextureView.InsertImageBarrier(
|
|
||||||
_gd.Api,
|
_gd.Api,
|
||||||
cbs.CommandBuffer,
|
cbs.CommandBuffer,
|
||||||
_imageAuto.Get(cbs).Value,
|
|
||||||
_lastModificationAccess,
|
_lastModificationAccess,
|
||||||
dstAccessFlags,
|
dstAccessFlags,
|
||||||
_lastModificationStage,
|
_lastModificationStage,
|
||||||
dstStageFlags,
|
dstStageFlags);
|
||||||
aspectFlags,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
_info.GetLayers(),
|
|
||||||
_info.Levels);
|
|
||||||
|
|
||||||
_lastModificationAccess = AccessFlags.None;
|
_lastModificationAccess = AccessFlags.None;
|
||||||
}
|
}
|
||||||
|
@ -435,6 +435,34 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ImageAspectFlags.ColorBit);
|
ImageAspectFlags.ColorBit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static unsafe void InsertMemoryBarrier(
|
||||||
|
Vk api,
|
||||||
|
CommandBuffer commandBuffer,
|
||||||
|
AccessFlags srcAccessMask,
|
||||||
|
AccessFlags dstAccessMask,
|
||||||
|
PipelineStageFlags srcStageMask,
|
||||||
|
PipelineStageFlags dstStageMask)
|
||||||
|
{
|
||||||
|
MemoryBarrier memoryBarrier = new()
|
||||||
|
{
|
||||||
|
SType = StructureType.MemoryBarrier,
|
||||||
|
SrcAccessMask = srcAccessMask,
|
||||||
|
DstAccessMask = dstAccessMask,
|
||||||
|
};
|
||||||
|
|
||||||
|
api.CmdPipelineBarrier(
|
||||||
|
commandBuffer,
|
||||||
|
srcStageMask,
|
||||||
|
dstStageMask,
|
||||||
|
DependencyFlags.None,
|
||||||
|
1,
|
||||||
|
memoryBarrier,
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
public static unsafe void InsertImageBarrier(
|
public static unsafe void InsertImageBarrier(
|
||||||
Vk api,
|
Vk api,
|
||||||
CommandBuffer commandBuffer,
|
CommandBuffer commandBuffer,
|
||||||
|
@ -327,6 +327,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
features2.Features.OcclusionQueryPrecise,
|
features2.Features.OcclusionQueryPrecise,
|
||||||
_physicalDevice.PhysicalDeviceFeatures.PipelineStatisticsQuery,
|
_physicalDevice.PhysicalDeviceFeatures.PipelineStatisticsQuery,
|
||||||
_physicalDevice.PhysicalDeviceFeatures.GeometryShader,
|
_physicalDevice.PhysicalDeviceFeatures.GeometryShader,
|
||||||
|
_physicalDevice.PhysicalDeviceFeatures.TessellationShader,
|
||||||
_physicalDevice.IsDeviceExtensionPresent("VK_NV_viewport_array2"),
|
_physicalDevice.IsDeviceExtensionPresent("VK_NV_viewport_array2"),
|
||||||
_physicalDevice.IsDeviceExtensionPresent(ExtExternalMemoryHost.ExtensionName),
|
_physicalDevice.IsDeviceExtensionPresent(ExtExternalMemoryHost.ExtensionName),
|
||||||
supportsDepthClipControl && featuresDepthClipControl.DepthClipControl,
|
supportsDepthClipControl && featuresDepthClipControl.DepthClipControl,
|
||||||
|
@ -22,8 +22,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private Image[] _swapchainImages;
|
private Image[] _swapchainImages;
|
||||||
private Auto<DisposableImageView>[] _swapchainImageViews;
|
private Auto<DisposableImageView>[] _swapchainImageViews;
|
||||||
|
|
||||||
private Semaphore _imageAvailableSemaphore;
|
private Semaphore[] _imageAvailableSemaphores;
|
||||||
private Semaphore _renderFinishedSemaphore;
|
private Semaphore[] _renderFinishedSemaphores;
|
||||||
|
|
||||||
|
private int _frameIndex;
|
||||||
|
|
||||||
private int _width;
|
private int _width;
|
||||||
private int _height;
|
private int _height;
|
||||||
@ -48,14 +50,6 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_surface = surface;
|
_surface = surface;
|
||||||
|
|
||||||
CreateSwapchain();
|
CreateSwapchain();
|
||||||
|
|
||||||
var semaphoreCreateInfo = new SemaphoreCreateInfo
|
|
||||||
{
|
|
||||||
SType = StructureType.SemaphoreCreateInfo,
|
|
||||||
};
|
|
||||||
|
|
||||||
gd.Api.CreateSemaphore(device, semaphoreCreateInfo, null, out _imageAvailableSemaphore).ThrowOnError();
|
|
||||||
gd.Api.CreateSemaphore(device, semaphoreCreateInfo, null, out _renderFinishedSemaphore).ThrowOnError();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecreateSwapchain()
|
private void RecreateSwapchain()
|
||||||
@ -69,7 +63,22 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Destroy old Swapchain.
|
// Destroy old Swapchain.
|
||||||
|
|
||||||
_gd.Api.DeviceWaitIdle(_device);
|
_gd.Api.DeviceWaitIdle(_device);
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _imageAvailableSemaphores.Length; i++)
|
||||||
|
{
|
||||||
|
_gd.Api.DestroySemaphore(_device, _imageAvailableSemaphores[i], null);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _renderFinishedSemaphores.Length; i++)
|
||||||
|
{
|
||||||
|
_gd.Api.DestroySemaphore(_device, _renderFinishedSemaphores[i], null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_gd.SwapchainApi.DestroySwapchain(_device, oldSwapchain, Span<AllocationCallbacks>.Empty);
|
_gd.SwapchainApi.DestroySwapchain(_device, oldSwapchain, Span<AllocationCallbacks>.Empty);
|
||||||
|
|
||||||
CreateSwapchain();
|
CreateSwapchain();
|
||||||
@ -151,6 +160,25 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
_swapchainImageViews[i] = CreateSwapchainImageView(_swapchainImages[i], surfaceFormat.Format);
|
_swapchainImageViews[i] = CreateSwapchainImageView(_swapchainImages[i], surfaceFormat.Format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var semaphoreCreateInfo = new SemaphoreCreateInfo
|
||||||
|
{
|
||||||
|
SType = StructureType.SemaphoreCreateInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
_imageAvailableSemaphores = new Semaphore[imageCount];
|
||||||
|
|
||||||
|
for (int i = 0; i < _imageAvailableSemaphores.Length; i++)
|
||||||
|
{
|
||||||
|
_gd.Api.CreateSemaphore(_device, semaphoreCreateInfo, null, out _imageAvailableSemaphores[i]).ThrowOnError();
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderFinishedSemaphores = new Semaphore[imageCount];
|
||||||
|
|
||||||
|
for (int i = 0; i < _renderFinishedSemaphores.Length; i++)
|
||||||
|
{
|
||||||
|
_gd.Api.CreateSemaphore(_device, semaphoreCreateInfo, null, out _renderFinishedSemaphores[i]).ThrowOnError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe Auto<DisposableImageView> CreateSwapchainImageView(Image swapchainImage, VkFormat format)
|
private unsafe Auto<DisposableImageView> CreateSwapchainImageView(Image swapchainImage, VkFormat format)
|
||||||
@ -185,6 +213,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
return new SurfaceFormatKHR(VkFormat.B8G8R8A8Unorm, ColorSpaceKHR.PaceSrgbNonlinearKhr);
|
return new SurfaceFormatKHR(VkFormat.B8G8R8A8Unorm, ColorSpaceKHR.PaceSrgbNonlinearKhr);
|
||||||
}
|
}
|
||||||
|
|
||||||
var formatToReturn = availableFormats[0];
|
var formatToReturn = availableFormats[0];
|
||||||
if (colorSpacePassthroughEnabled)
|
if (colorSpacePassthroughEnabled)
|
||||||
{
|
{
|
||||||
@ -212,6 +241,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatToReturn;
|
return formatToReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,6 +295,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_gd.PipelineInternal.AutoFlush.Present();
|
_gd.PipelineInternal.AutoFlush.Present();
|
||||||
|
|
||||||
uint nextImage = 0;
|
uint nextImage = 0;
|
||||||
|
int semaphoreIndex = _frameIndex++ % _imageAvailableSemaphores.Length;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@ -272,7 +303,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_device,
|
_device,
|
||||||
_swapchain,
|
_swapchain,
|
||||||
ulong.MaxValue,
|
ulong.MaxValue,
|
||||||
_imageAvailableSemaphore,
|
_imageAvailableSemaphores[semaphoreIndex],
|
||||||
new Fence(),
|
new Fence(),
|
||||||
ref nextImage);
|
ref nextImage);
|
||||||
|
|
||||||
@ -411,12 +442,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
_gd.CommandBufferPool.Return(
|
_gd.CommandBufferPool.Return(
|
||||||
cbs,
|
cbs,
|
||||||
stackalloc[] { _imageAvailableSemaphore },
|
stackalloc[] { _imageAvailableSemaphores[semaphoreIndex] },
|
||||||
stackalloc[] { PipelineStageFlags.ColorAttachmentOutputBit },
|
stackalloc[] { PipelineStageFlags.ColorAttachmentOutputBit },
|
||||||
stackalloc[] { _renderFinishedSemaphore });
|
stackalloc[] { _renderFinishedSemaphores[semaphoreIndex] });
|
||||||
|
|
||||||
// TODO: Present queue.
|
// TODO: Present queue.
|
||||||
var semaphore = _renderFinishedSemaphore;
|
var semaphore = _renderFinishedSemaphores[semaphoreIndex];
|
||||||
var swapchain = _swapchain;
|
var swapchain = _swapchain;
|
||||||
|
|
||||||
Result result;
|
Result result;
|
||||||
@ -593,14 +624,21 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
_gd.Api.DestroySemaphore(_device, _renderFinishedSemaphore, null);
|
|
||||||
_gd.Api.DestroySemaphore(_device, _imageAvailableSemaphore, null);
|
|
||||||
|
|
||||||
for (int i = 0; i < _swapchainImageViews.Length; i++)
|
for (int i = 0; i < _swapchainImageViews.Length; i++)
|
||||||
{
|
{
|
||||||
_swapchainImageViews[i].Dispose();
|
_swapchainImageViews[i].Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _imageAvailableSemaphores.Length; i++)
|
||||||
|
{
|
||||||
|
_gd.Api.DestroySemaphore(_device, _imageAvailableSemaphores[i], null);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _renderFinishedSemaphores.Length; i++)
|
||||||
|
{
|
||||||
|
_gd.Api.DestroySemaphore(_device, _renderFinishedSemaphores[i], null);
|
||||||
|
}
|
||||||
|
|
||||||
_gd.SwapchainApi.DestroySwapchain(_device, _swapchain, null);
|
_gd.SwapchainApi.DestroySwapchain(_device, _swapchain, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ using Ryujinx.HLE.HOS.Services.Settings.Types;
|
|||||||
using Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService;
|
using Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService;
|
||||||
using Ryujinx.HLE.HOS.SystemState;
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
|
using Ryujinx.Horizon.Sdk.Lbl;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
|
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
|
||||||
@ -15,7 +16,6 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
|
|||||||
|
|
||||||
private readonly Apm.ManagerServer _apmManagerServer;
|
private readonly Apm.ManagerServer _apmManagerServer;
|
||||||
private readonly Apm.SystemManagerServer _apmSystemManagerServer;
|
private readonly Apm.SystemManagerServer _apmSystemManagerServer;
|
||||||
private readonly Lbl.LblControllerServer _lblControllerServer;
|
|
||||||
|
|
||||||
private bool _vrModeEnabled;
|
private bool _vrModeEnabled;
|
||||||
#pragma warning disable CS0414, IDE0052 // Remove unread private member
|
#pragma warning disable CS0414, IDE0052 // Remove unread private member
|
||||||
@ -34,7 +34,6 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
|
|||||||
|
|
||||||
_apmManagerServer = new Apm.ManagerServer(context);
|
_apmManagerServer = new Apm.ManagerServer(context);
|
||||||
_apmSystemManagerServer = new Apm.SystemManagerServer(context);
|
_apmSystemManagerServer = new Apm.SystemManagerServer(context);
|
||||||
_lblControllerServer = new Lbl.LblControllerServer(context);
|
|
||||||
|
|
||||||
_acquiredSleepLockEvent = new KEvent(context.Device.System.KernelContext);
|
_acquiredSleepLockEvent = new KEvent(context.Device.System.KernelContext);
|
||||||
}
|
}
|
||||||
@ -215,13 +214,15 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
|
|||||||
|
|
||||||
_vrModeEnabled = vrModeEnabled;
|
_vrModeEnabled = vrModeEnabled;
|
||||||
|
|
||||||
|
using var lblApi = new LblApi();
|
||||||
|
|
||||||
if (vrModeEnabled)
|
if (vrModeEnabled)
|
||||||
{
|
{
|
||||||
_lblControllerServer.EnableVrMode();
|
lblApi.EnableVrMode().AbortOnFailure();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_lblControllerServer.DisableVrMode();
|
lblApi.DisableVrMode().AbortOnFailure();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: It signals an internal event of ICommonStateGetter. We have to determine where this event is used.
|
// TODO: It signals an internal event of ICommonStateGetter. We have to determine where this event is used.
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
namespace Ryujinx.HLE.HOS.Services.Lbl
|
|
||||||
{
|
|
||||||
abstract class ILblController : IpcService
|
|
||||||
{
|
|
||||||
public ILblController(ServiceCtx context) { }
|
|
||||||
|
|
||||||
protected abstract void SetCurrentBrightnessSettingForVrMode(float currentBrightnessSettingForVrMode);
|
|
||||||
protected abstract float GetCurrentBrightnessSettingForVrMode();
|
|
||||||
internal abstract void EnableVrMode();
|
|
||||||
internal abstract void DisableVrMode();
|
|
||||||
protected abstract bool IsVrModeEnabled();
|
|
||||||
|
|
||||||
[CommandCmif(17)]
|
|
||||||
// SetBrightnessReflectionDelayLevel(float, float)
|
|
||||||
public ResultCode SetBrightnessReflectionDelayLevel(ServiceCtx context)
|
|
||||||
{
|
|
||||||
return ResultCode.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
[CommandCmif(18)]
|
|
||||||
// GetBrightnessReflectionDelayLevel(float) -> float
|
|
||||||
public ResultCode GetBrightnessReflectionDelayLevel(ServiceCtx context)
|
|
||||||
{
|
|
||||||
context.ResponseData.Write(0.0f);
|
|
||||||
|
|
||||||
return ResultCode.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
[CommandCmif(21)]
|
|
||||||
// SetCurrentAmbientLightSensorMapping(unknown<0xC>)
|
|
||||||
public ResultCode SetCurrentAmbientLightSensorMapping(ServiceCtx context)
|
|
||||||
{
|
|
||||||
return ResultCode.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
[CommandCmif(22)]
|
|
||||||
// GetCurrentAmbientLightSensorMapping() -> unknown<0xC>
|
|
||||||
public ResultCode GetCurrentAmbientLightSensorMapping(ServiceCtx context)
|
|
||||||
{
|
|
||||||
return ResultCode.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
[CommandCmif(24)] // 3.0.0+
|
|
||||||
// SetCurrentBrightnessSettingForVrMode(float)
|
|
||||||
public ResultCode SetCurrentBrightnessSettingForVrMode(ServiceCtx context)
|
|
||||||
{
|
|
||||||
float currentBrightnessSettingForVrMode = context.RequestData.ReadSingle();
|
|
||||||
|
|
||||||
SetCurrentBrightnessSettingForVrMode(currentBrightnessSettingForVrMode);
|
|
||||||
|
|
||||||
return ResultCode.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
[CommandCmif(25)] // 3.0.0+
|
|
||||||
// GetCurrentBrightnessSettingForVrMode() -> float
|
|
||||||
public ResultCode GetCurrentBrightnessSettingForVrMode(ServiceCtx context)
|
|
||||||
{
|
|
||||||
float currentBrightnessSettingForVrMode = GetCurrentBrightnessSettingForVrMode();
|
|
||||||
|
|
||||||
context.ResponseData.Write(currentBrightnessSettingForVrMode);
|
|
||||||
|
|
||||||
return ResultCode.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
[CommandCmif(26)] // 3.0.0+
|
|
||||||
// EnableVrMode()
|
|
||||||
public ResultCode EnableVrMode(ServiceCtx context)
|
|
||||||
{
|
|
||||||
EnableVrMode();
|
|
||||||
|
|
||||||
return ResultCode.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
[CommandCmif(27)] // 3.0.0+
|
|
||||||
// DisableVrMode()
|
|
||||||
public ResultCode DisableVrMode(ServiceCtx context)
|
|
||||||
{
|
|
||||||
DisableVrMode();
|
|
||||||
|
|
||||||
return ResultCode.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
[CommandCmif(28)] // 3.0.0+
|
|
||||||
// IsVrModeEnabled() -> bool
|
|
||||||
public ResultCode IsVrModeEnabled(ServiceCtx context)
|
|
||||||
{
|
|
||||||
context.ResponseData.Write(IsVrModeEnabled());
|
|
||||||
|
|
||||||
return ResultCode.Success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
namespace Ryujinx.HLE.HOS.Services.Lbl
|
|
||||||
{
|
|
||||||
[Service("lbl")]
|
|
||||||
class LblControllerServer : ILblController
|
|
||||||
{
|
|
||||||
private bool _vrModeEnabled;
|
|
||||||
private float _currentBrightnessSettingForVrMode;
|
|
||||||
|
|
||||||
public LblControllerServer(ServiceCtx context) : base(context) { }
|
|
||||||
|
|
||||||
protected override void SetCurrentBrightnessSettingForVrMode(float currentBrightnessSettingForVrMode)
|
|
||||||
{
|
|
||||||
if (float.IsNaN(currentBrightnessSettingForVrMode) || float.IsInfinity(currentBrightnessSettingForVrMode))
|
|
||||||
{
|
|
||||||
_currentBrightnessSettingForVrMode = 0.0f;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentBrightnessSettingForVrMode = currentBrightnessSettingForVrMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override float GetCurrentBrightnessSettingForVrMode()
|
|
||||||
{
|
|
||||||
if (float.IsNaN(_currentBrightnessSettingForVrMode) || float.IsInfinity(_currentBrightnessSettingForVrMode))
|
|
||||||
{
|
|
||||||
return 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _currentBrightnessSettingForVrMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal override void EnableVrMode()
|
|
||||||
{
|
|
||||||
_vrModeEnabled = true;
|
|
||||||
|
|
||||||
// NOTE: Service check _vrModeEnabled field value in a thread and then change the screen brightness.
|
|
||||||
// Since we don't support that. It's fine to do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
internal override void DisableVrMode()
|
|
||||||
{
|
|
||||||
_vrModeEnabled = false;
|
|
||||||
|
|
||||||
// NOTE: Service check _vrModeEnabled field value in a thread and then change the screen brightness.
|
|
||||||
// Since we don't support that. It's fine to do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsVrModeEnabled()
|
|
||||||
{
|
|
||||||
return _vrModeEnabled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,6 +6,7 @@ using Ryujinx.HLE.HOS.Kernel;
|
|||||||
using Ryujinx.HLE.HOS.Kernel.Ipc;
|
using Ryujinx.HLE.HOS.Kernel.Ipc;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Process;
|
using Ryujinx.HLE.HOS.Kernel.Process;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||||
|
using Ryujinx.Horizon;
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
@ -172,6 +173,13 @@ namespace Ryujinx.HLE.HOS.Services
|
|||||||
_selfProcess = KernelStatic.GetCurrentProcess();
|
_selfProcess = KernelStatic.GetCurrentProcess();
|
||||||
_selfThread = KernelStatic.GetCurrentThread();
|
_selfThread = KernelStatic.GetCurrentThread();
|
||||||
|
|
||||||
|
HorizonStatic.Register(
|
||||||
|
default,
|
||||||
|
_context.Syscall,
|
||||||
|
_selfProcess.CpuMemory,
|
||||||
|
_selfThread.ThreadContext,
|
||||||
|
(int)_selfThread.ThreadContext.GetX(1));
|
||||||
|
|
||||||
if (SmObjectFactory != null)
|
if (SmObjectFactory != null)
|
||||||
{
|
{
|
||||||
_context.Syscall.ManageNamedPort(out int serverPortHandle, "sm:", 50);
|
_context.Syscall.ManageNamedPort(out int serverPortHandle, "sm:", 50);
|
||||||
|
@ -6,8 +6,8 @@ namespace Ryujinx.Horizon.Bcat
|
|||||||
{
|
{
|
||||||
internal class BcatIpcServer
|
internal class BcatIpcServer
|
||||||
{
|
{
|
||||||
private const int BcatMaxSessionsCount = 8;
|
private const int MaxSessionsCount = 8;
|
||||||
private const int BcatTotalMaxSessionsCount = BcatMaxSessionsCount * 4;
|
private const int TotalMaxSessionsCount = MaxSessionsCount * 4;
|
||||||
|
|
||||||
private const int PointerBufferSize = 0x400;
|
private const int PointerBufferSize = 0x400;
|
||||||
private const int MaxDomains = 64;
|
private const int MaxDomains = 64;
|
||||||
@ -17,7 +17,7 @@ namespace Ryujinx.Horizon.Bcat
|
|||||||
private SmApi _sm;
|
private SmApi _sm;
|
||||||
private BcatServerManager _serverManager;
|
private BcatServerManager _serverManager;
|
||||||
|
|
||||||
private static readonly ManagerOptions _bcatManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||||
|
|
||||||
internal void Initialize()
|
internal void Initialize()
|
||||||
{
|
{
|
||||||
@ -26,13 +26,13 @@ namespace Ryujinx.Horizon.Bcat
|
|||||||
_sm = new SmApi();
|
_sm = new SmApi();
|
||||||
_sm.Initialize().AbortOnFailure();
|
_sm.Initialize().AbortOnFailure();
|
||||||
|
|
||||||
_serverManager = new BcatServerManager(allocator, _sm, MaxPortsCount, _bcatManagerOptions, BcatTotalMaxSessionsCount);
|
_serverManager = new BcatServerManager(allocator, _sm, MaxPortsCount, _managerOptions, TotalMaxSessionsCount);
|
||||||
|
|
||||||
#pragma warning disable IDE0055 // Disable formatting
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
_serverManager.RegisterServer((int)BcatPortIndex.Admin, ServiceName.Encode("bcat:a"), BcatMaxSessionsCount);
|
_serverManager.RegisterServer((int)BcatPortIndex.Admin, ServiceName.Encode("bcat:a"), MaxSessionsCount);
|
||||||
_serverManager.RegisterServer((int)BcatPortIndex.Manager, ServiceName.Encode("bcat:m"), BcatMaxSessionsCount);
|
_serverManager.RegisterServer((int)BcatPortIndex.Manager, ServiceName.Encode("bcat:m"), MaxSessionsCount);
|
||||||
_serverManager.RegisterServer((int)BcatPortIndex.User, ServiceName.Encode("bcat:u"), BcatMaxSessionsCount);
|
_serverManager.RegisterServer((int)BcatPortIndex.User, ServiceName.Encode("bcat:u"), MaxSessionsCount);
|
||||||
_serverManager.RegisterServer((int)BcatPortIndex.System, ServiceName.Encode("bcat:s"), BcatMaxSessionsCount);
|
_serverManager.RegisterServer((int)BcatPortIndex.System, ServiceName.Encode("bcat:s"), MaxSessionsCount);
|
||||||
#pragma warning restore IDE0055
|
#pragma warning restore IDE0055
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ using System;
|
|||||||
|
|
||||||
namespace Ryujinx.Horizon
|
namespace Ryujinx.Horizon
|
||||||
{
|
{
|
||||||
static class HorizonStatic
|
public static class HorizonStatic
|
||||||
{
|
{
|
||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
private static HorizonOptions _options;
|
private static HorizonOptions _options;
|
||||||
|
130
src/Ryujinx.Horizon/Lbl/Ipc/LblController.cs
Normal file
130
src/Ryujinx.Horizon/Lbl/Ipc/LblController.cs
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
using Ryujinx.Horizon.Common;
|
||||||
|
using Ryujinx.Horizon.Sdk.Lbl;
|
||||||
|
using Ryujinx.Horizon.Sdk.Sf;
|
||||||
|
|
||||||
|
namespace Ryujinx.Horizon.Lbl.Ipc
|
||||||
|
{
|
||||||
|
partial class LblController : ILblController
|
||||||
|
{
|
||||||
|
private bool _vrModeEnabled;
|
||||||
|
private float _currentBrightnessSettingForVrMode;
|
||||||
|
|
||||||
|
[CmifCommand(17)]
|
||||||
|
public Result SetBrightnessReflectionDelayLevel(float unknown0, float unknown1)
|
||||||
|
{
|
||||||
|
// NOTE: Stubbed in system module.
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CmifCommand(18)]
|
||||||
|
public Result GetBrightnessReflectionDelayLevel(out float unknown1, float unknown0)
|
||||||
|
{
|
||||||
|
// NOTE: Stubbed in system module.
|
||||||
|
|
||||||
|
unknown1 = 0.0f;
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CmifCommand(19)]
|
||||||
|
public Result SetCurrentBrightnessMapping(float unknown0, float unknown1, float unknown2)
|
||||||
|
{
|
||||||
|
// NOTE: Stubbed in system module.
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CmifCommand(20)]
|
||||||
|
public Result GetCurrentBrightnessMapping(out float unknown0, out float unknown1, out float unknown2)
|
||||||
|
{
|
||||||
|
// NOTE: Stubbed in system module.
|
||||||
|
|
||||||
|
unknown0 = 0.0f;
|
||||||
|
unknown1 = 0.0f;
|
||||||
|
unknown2 = 0.0f;
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CmifCommand(21)]
|
||||||
|
public Result SetCurrentAmbientLightSensorMapping(float unknown0, float unknown1, float unknown2)
|
||||||
|
{
|
||||||
|
// NOTE: Stubbed in system module.
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CmifCommand(22)]
|
||||||
|
public Result GetCurrentAmbientLightSensorMapping(out float unknown0, out float unknown1, out float unknown2)
|
||||||
|
{
|
||||||
|
// NOTE: Stubbed in system module.
|
||||||
|
|
||||||
|
unknown0 = 0.0f;
|
||||||
|
unknown1 = 0.0f;
|
||||||
|
unknown2 = 0.0f;
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CmifCommand(24)]
|
||||||
|
public Result SetCurrentBrightnessSettingForVrMode(float currentBrightnessSettingForVrMode)
|
||||||
|
{
|
||||||
|
if (float.IsNaN(currentBrightnessSettingForVrMode) || float.IsInfinity(currentBrightnessSettingForVrMode))
|
||||||
|
{
|
||||||
|
_currentBrightnessSettingForVrMode = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_currentBrightnessSettingForVrMode = currentBrightnessSettingForVrMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CmifCommand(25)]
|
||||||
|
public Result GetCurrentBrightnessSettingForVrMode(out float currentBrightnessSettingForVrMode)
|
||||||
|
{
|
||||||
|
if (float.IsNaN(_currentBrightnessSettingForVrMode) || float.IsInfinity(_currentBrightnessSettingForVrMode))
|
||||||
|
{
|
||||||
|
currentBrightnessSettingForVrMode = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentBrightnessSettingForVrMode = _currentBrightnessSettingForVrMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CmifCommand(26)]
|
||||||
|
public Result EnableVrMode()
|
||||||
|
{
|
||||||
|
_vrModeEnabled = true;
|
||||||
|
|
||||||
|
// NOTE: The service checks _vrModeEnabled field value in a thread and then changes the screen brightness.
|
||||||
|
// Since we don't support that, it's fine to do nothing.
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CmifCommand(27)]
|
||||||
|
public Result DisableVrMode()
|
||||||
|
{
|
||||||
|
_vrModeEnabled = false;
|
||||||
|
|
||||||
|
// NOTE: The service checks _vrModeEnabled field value in a thread and then changes the screen brightness.
|
||||||
|
// Since we don't support that, it's fine to do nothing.
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CmifCommand(28)]
|
||||||
|
public Result IsVrModeEnabled(out bool vrModeEnabled)
|
||||||
|
{
|
||||||
|
vrModeEnabled = _vrModeEnabled;
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
src/Ryujinx.Horizon/Lbl/LblIpcServer.cs
Normal file
43
src/Ryujinx.Horizon/Lbl/LblIpcServer.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using Ryujinx.Horizon.Lbl.Ipc;
|
||||||
|
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
||||||
|
using Ryujinx.Horizon.Sdk.Sm;
|
||||||
|
|
||||||
|
namespace Ryujinx.Horizon.Lbl
|
||||||
|
{
|
||||||
|
class LblIpcServer
|
||||||
|
{
|
||||||
|
private const int MaxSessionsCount = 5;
|
||||||
|
|
||||||
|
private const int PointerBufferSize = 0;
|
||||||
|
private const int MaxDomains = 0;
|
||||||
|
private const int MaxDomainObjects = 0;
|
||||||
|
private const int MaxPortsCount = 1;
|
||||||
|
|
||||||
|
private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||||
|
|
||||||
|
private SmApi _sm;
|
||||||
|
private ServerManager _serverManager;
|
||||||
|
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
HeapAllocator allocator = new();
|
||||||
|
|
||||||
|
_sm = new SmApi();
|
||||||
|
_sm.Initialize().AbortOnFailure();
|
||||||
|
|
||||||
|
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _managerOptions, MaxSessionsCount);
|
||||||
|
|
||||||
|
_serverManager.RegisterObjectForServer(new LblController(), ServiceName.Encode("lbl"), MaxSessionsCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ServiceRequests()
|
||||||
|
{
|
||||||
|
_serverManager.ServiceRequests();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Shutdown()
|
||||||
|
{
|
||||||
|
_serverManager.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
src/Ryujinx.Horizon/Lbl/LblMain.cs
Normal file
17
src/Ryujinx.Horizon/Lbl/LblMain.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace Ryujinx.Horizon.Lbl
|
||||||
|
{
|
||||||
|
class LblMain : IService
|
||||||
|
{
|
||||||
|
public static void Main(ServiceTable serviceTable)
|
||||||
|
{
|
||||||
|
LblIpcServer ipcServer = new();
|
||||||
|
|
||||||
|
ipcServer.Initialize();
|
||||||
|
|
||||||
|
serviceTable.SignalServiceReady();
|
||||||
|
|
||||||
|
ipcServer.ServiceRequests();
|
||||||
|
ipcServer.Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,14 +6,14 @@ namespace Ryujinx.Horizon.LogManager
|
|||||||
{
|
{
|
||||||
class LmIpcServer
|
class LmIpcServer
|
||||||
{
|
{
|
||||||
private const int LogMaxSessionsCount = 42;
|
private const int MaxSessionsCount = 42;
|
||||||
|
|
||||||
private const int PointerBufferSize = 0x400;
|
private const int PointerBufferSize = 0x400;
|
||||||
private const int MaxDomains = 31;
|
private const int MaxDomains = 31;
|
||||||
private const int MaxDomainObjects = 61;
|
private const int MaxDomainObjects = 61;
|
||||||
private const int MaxPortsCount = 1;
|
private const int MaxPortsCount = 1;
|
||||||
|
|
||||||
private static readonly ManagerOptions _logManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||||
|
|
||||||
private SmApi _sm;
|
private SmApi _sm;
|
||||||
private ServerManager _serverManager;
|
private ServerManager _serverManager;
|
||||||
@ -25,9 +25,9 @@ namespace Ryujinx.Horizon.LogManager
|
|||||||
_sm = new SmApi();
|
_sm = new SmApi();
|
||||||
_sm.Initialize().AbortOnFailure();
|
_sm.Initialize().AbortOnFailure();
|
||||||
|
|
||||||
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _logManagerOptions, LogMaxSessionsCount);
|
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _managerOptions, MaxSessionsCount);
|
||||||
|
|
||||||
_serverManager.RegisterObjectForServer(new LogService(), ServiceName.Encode("lm"), LogMaxSessionsCount);
|
_serverManager.RegisterObjectForServer(new LogService(), ServiceName.Encode("lm"), MaxSessionsCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ServiceRequests()
|
public void ServiceRequests()
|
||||||
|
@ -6,14 +6,14 @@ namespace Ryujinx.Horizon.MmNv
|
|||||||
{
|
{
|
||||||
class MmNvIpcServer
|
class MmNvIpcServer
|
||||||
{
|
{
|
||||||
private const int MmNvMaxSessionsCount = 9;
|
private const int MaxSessionsCount = 40;
|
||||||
|
|
||||||
private const int PointerBufferSize = 0;
|
private const int PointerBufferSize = 0;
|
||||||
private const int MaxDomains = 0;
|
private const int MaxDomains = 0;
|
||||||
private const int MaxDomainObjects = 0;
|
private const int MaxDomainObjects = 0;
|
||||||
private const int MaxPortsCount = 1;
|
private const int MaxPortsCount = 1;
|
||||||
|
|
||||||
private static readonly ManagerOptions _mmNvOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||||
|
|
||||||
private SmApi _sm;
|
private SmApi _sm;
|
||||||
private ServerManager _serverManager;
|
private ServerManager _serverManager;
|
||||||
@ -25,9 +25,9 @@ namespace Ryujinx.Horizon.MmNv
|
|||||||
_sm = new SmApi();
|
_sm = new SmApi();
|
||||||
_sm.Initialize().AbortOnFailure();
|
_sm.Initialize().AbortOnFailure();
|
||||||
|
|
||||||
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _mmNvOptions, MmNvMaxSessionsCount);
|
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _managerOptions, MaxSessionsCount);
|
||||||
|
|
||||||
_serverManager.RegisterObjectForServer(new Request(), ServiceName.Encode("mm:u"), MmNvMaxSessionsCount);
|
_serverManager.RegisterObjectForServer(new Request(), ServiceName.Encode("mm:u"), MaxSessionsCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ServiceRequests()
|
public void ServiceRequests()
|
||||||
|
@ -6,15 +6,15 @@ namespace Ryujinx.Horizon.Prepo
|
|||||||
{
|
{
|
||||||
class PrepoIpcServer
|
class PrepoIpcServer
|
||||||
{
|
{
|
||||||
private const int PrepoMaxSessionsCount = 12;
|
private const int MaxSessionsCount = 12;
|
||||||
private const int PrepoTotalMaxSessionsCount = PrepoMaxSessionsCount * 6;
|
private const int TotalMaxSessionsCount = MaxSessionsCount * 6;
|
||||||
|
|
||||||
private const int PointerBufferSize = 0x80;
|
private const int PointerBufferSize = 0x80;
|
||||||
private const int MaxDomains = 64;
|
private const int MaxDomains = 64;
|
||||||
private const int MaxDomainObjects = 16;
|
private const int MaxDomainObjects = 16;
|
||||||
private const int MaxPortsCount = 6;
|
private const int MaxPortsCount = 6;
|
||||||
|
|
||||||
private static readonly ManagerOptions _prepoManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||||
|
|
||||||
private SmApi _sm;
|
private SmApi _sm;
|
||||||
private PrepoServerManager _serverManager;
|
private PrepoServerManager _serverManager;
|
||||||
@ -26,15 +26,15 @@ namespace Ryujinx.Horizon.Prepo
|
|||||||
_sm = new SmApi();
|
_sm = new SmApi();
|
||||||
_sm.Initialize().AbortOnFailure();
|
_sm.Initialize().AbortOnFailure();
|
||||||
|
|
||||||
_serverManager = new PrepoServerManager(allocator, _sm, MaxPortsCount, _prepoManagerOptions, PrepoTotalMaxSessionsCount);
|
_serverManager = new PrepoServerManager(allocator, _sm, MaxPortsCount, _managerOptions, TotalMaxSessionsCount);
|
||||||
|
|
||||||
#pragma warning disable IDE0055 // Disable formatting
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
_serverManager.RegisterServer((int)PrepoPortIndex.Admin, ServiceName.Encode("prepo:a"), PrepoMaxSessionsCount); // 1.0.0-5.1.0
|
_serverManager.RegisterServer((int)PrepoPortIndex.Admin, ServiceName.Encode("prepo:a"), MaxSessionsCount); // 1.0.0-5.1.0
|
||||||
_serverManager.RegisterServer((int)PrepoPortIndex.Admin2, ServiceName.Encode("prepo:a2"), PrepoMaxSessionsCount); // 6.0.0+
|
_serverManager.RegisterServer((int)PrepoPortIndex.Admin2, ServiceName.Encode("prepo:a2"), MaxSessionsCount); // 6.0.0+
|
||||||
_serverManager.RegisterServer((int)PrepoPortIndex.Manager, ServiceName.Encode("prepo:m"), PrepoMaxSessionsCount);
|
_serverManager.RegisterServer((int)PrepoPortIndex.Manager, ServiceName.Encode("prepo:m"), MaxSessionsCount);
|
||||||
_serverManager.RegisterServer((int)PrepoPortIndex.User, ServiceName.Encode("prepo:u"), PrepoMaxSessionsCount);
|
_serverManager.RegisterServer((int)PrepoPortIndex.User, ServiceName.Encode("prepo:u"), MaxSessionsCount);
|
||||||
_serverManager.RegisterServer((int)PrepoPortIndex.System, ServiceName.Encode("prepo:s"), PrepoMaxSessionsCount);
|
_serverManager.RegisterServer((int)PrepoPortIndex.System, ServiceName.Encode("prepo:s"), MaxSessionsCount);
|
||||||
_serverManager.RegisterServer((int)PrepoPortIndex.Debug, ServiceName.Encode("prepo:d"), PrepoMaxSessionsCount); // 1.0.0
|
_serverManager.RegisterServer((int)PrepoPortIndex.Debug, ServiceName.Encode("prepo:d"), MaxSessionsCount); // 1.0.0
|
||||||
#pragma warning restore IDE0055
|
#pragma warning restore IDE0055
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
src/Ryujinx.Horizon/Sdk/Lbl/ILblController.cs
Normal file
20
src/Ryujinx.Horizon/Sdk/Lbl/ILblController.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using Ryujinx.Horizon.Common;
|
||||||
|
using Ryujinx.Horizon.Sdk.Sf;
|
||||||
|
|
||||||
|
namespace Ryujinx.Horizon.Sdk.Lbl
|
||||||
|
{
|
||||||
|
interface ILblController : IServiceObject
|
||||||
|
{
|
||||||
|
Result SetBrightnessReflectionDelayLevel(float unknown0, float unknown1);
|
||||||
|
Result GetBrightnessReflectionDelayLevel(out float unknown1, float unknown0);
|
||||||
|
Result SetCurrentBrightnessMapping(float unknown0, float unknown1, float unknown2);
|
||||||
|
Result GetCurrentBrightnessMapping(out float unknown0, out float unknown1, out float unknown2);
|
||||||
|
Result SetCurrentAmbientLightSensorMapping(float unknown0, float unknown1, float unknown2);
|
||||||
|
Result GetCurrentAmbientLightSensorMapping(out float unknown0, out float unknown1, out float unknown2);
|
||||||
|
Result SetCurrentBrightnessSettingForVrMode(float currentBrightnessSettingForVrMode);
|
||||||
|
Result GetCurrentBrightnessSettingForVrMode(out float currentBrightnessSettingForVrMode);
|
||||||
|
Result EnableVrMode();
|
||||||
|
Result DisableVrMode();
|
||||||
|
Result IsVrModeEnabled(out bool vrModeEnabled);
|
||||||
|
}
|
||||||
|
}
|
43
src/Ryujinx.Horizon/Sdk/Lbl/LblApi.cs
Normal file
43
src/Ryujinx.Horizon/Sdk/Lbl/LblApi.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using Ryujinx.Horizon.Common;
|
||||||
|
using Ryujinx.Horizon.Sdk.Sm;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Horizon.Sdk.Lbl
|
||||||
|
{
|
||||||
|
public class LblApi : IDisposable
|
||||||
|
{
|
||||||
|
private const string LblName = "lbl";
|
||||||
|
|
||||||
|
private int _sessionHandle;
|
||||||
|
|
||||||
|
public LblApi()
|
||||||
|
{
|
||||||
|
using var smApi = new SmApi();
|
||||||
|
|
||||||
|
smApi.Initialize();
|
||||||
|
smApi.GetServiceHandle(out _sessionHandle, ServiceName.Encode(LblName)).AbortOnFailure();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result EnableVrMode()
|
||||||
|
{
|
||||||
|
return ServiceUtil.SendRequest(out _, _sessionHandle, 26, sendPid: false, ReadOnlySpan<byte>.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result DisableVrMode()
|
||||||
|
{
|
||||||
|
return ServiceUtil.SendRequest(out _, _sessionHandle, 27, sendPid: false, ReadOnlySpan<byte>.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_sessionHandle != 0)
|
||||||
|
{
|
||||||
|
HorizonStatic.Syscall.CloseHandle(_sessionHandle);
|
||||||
|
|
||||||
|
_sessionHandle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
|
|||||||
namespace Ryujinx.Horizon.Sdk.Sm
|
namespace Ryujinx.Horizon.Sdk.Sm
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
readonly struct ServiceName
|
public readonly struct ServiceName
|
||||||
{
|
{
|
||||||
public static ServiceName Invalid { get; } = new(0);
|
public static ServiceName Invalid { get; } = new(0);
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ using System;
|
|||||||
|
|
||||||
namespace Ryujinx.Horizon.Sdk.Sm
|
namespace Ryujinx.Horizon.Sdk.Sm
|
||||||
{
|
{
|
||||||
class SmApi
|
public class SmApi : IDisposable
|
||||||
{
|
{
|
||||||
private const string SmName = "sm:";
|
private const string SmName = "sm:";
|
||||||
|
|
||||||
@ -109,5 +109,17 @@ namespace Ryujinx.Horizon.Sdk.Sm
|
|||||||
|
|
||||||
return ServiceUtil.SendRequest(out _, _portHandle, 4, sendPid: true, data);
|
return ServiceUtil.SendRequest(out _, _portHandle, 4, sendPid: true, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_portHandle != 0)
|
||||||
|
{
|
||||||
|
HorizonStatic.Syscall.CloseHandle(_portHandle);
|
||||||
|
|
||||||
|
_portHandle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Ryujinx.Horizon.Bcat;
|
using Ryujinx.Horizon.Bcat;
|
||||||
|
using Ryujinx.Horizon.Lbl;
|
||||||
using Ryujinx.Horizon.LogManager;
|
using Ryujinx.Horizon.LogManager;
|
||||||
using Ryujinx.Horizon.MmNv;
|
using Ryujinx.Horizon.MmNv;
|
||||||
using Ryujinx.Horizon.Prepo;
|
using Ryujinx.Horizon.Prepo;
|
||||||
@ -23,10 +24,11 @@ namespace Ryujinx.Horizon
|
|||||||
entries.Add(new ServiceEntry(T.Main, this, options));
|
entries.Add(new ServiceEntry(T.Main, this, options));
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterService<LmMain>();
|
|
||||||
RegisterService<PrepoMain>();
|
|
||||||
RegisterService<BcatMain>();
|
RegisterService<BcatMain>();
|
||||||
|
RegisterService<LblMain>();
|
||||||
|
RegisterService<LmMain>();
|
||||||
RegisterService<MmNvMain>();
|
RegisterService<MmNvMain>();
|
||||||
|
RegisterService<PrepoMain>();
|
||||||
|
|
||||||
_totalServices = entries.Count;
|
_totalServices = entries.Count;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user