Compare commits

...

3 Commits

Author SHA1 Message Date
riperiperi
895d9b53bc Vulkan: Batch vertex buffer updates (#4843)
* Vulkan: Batch vertex buffer updates

Some games can bind a large number of vertex buffers for draws. This PR allows for vertex buffers to be updated with one call rather than one per buffer.

This mostly affects the AMD Mesa driver, the testing platform was Steam Deck with Super Mario Odyssey. It was taking about 12% before, should be greatly reduced now.

A small optimization has been added to avoid looking up the same buffer multiple times, as a common pattern is for the same buffer to be bound many times in a row with different ranges.

* Only rebind vertex buffers if they have changed

* Address feedback
2023-05-08 10:59:26 +02:00
Mary
0e06aace45 misc: Avoid copy of ApplicationControlProperty (#4849)
Avoid more giant copy when passing it around.
2023-05-08 01:50:07 +02:00
Ac_K
adf4ebcd60 Ava: Fix SystemTimeOffset calculation (#4848)
* Ava: Fix SystemTimeOffset calculation

During testing of #4822, Mary pointed out the way we calculate time offset is wrong in our Avalonia UI. This PR fixed that.
The axaml file is autoformatted too.

* DateTime.Now in local var
2023-05-08 00:31:08 +02:00
9 changed files with 200 additions and 120 deletions

View File

@@ -238,8 +238,9 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
} }
public DateTimeOffset DateOffset { get; set; } public DateTimeOffset CurrentDate { get; set; }
public TimeSpan TimeOffset { get; set; } public TimeSpan CurrentTime { get; set; }
internal AvaloniaList<TimeZone> TimeZones { get; set; } internal AvaloniaList<TimeZone> TimeZones { get; set; }
public AvaloniaList<string> GameDirectories { get; set; } public AvaloniaList<string> GameDirectories { get; set; }
public ObservableCollection<ComboBoxItem> AvailableGpus { get; set; } public ObservableCollection<ComboBoxItem> AvailableGpus { get; set; }
@@ -397,10 +398,11 @@ namespace Ryujinx.Ava.UI.ViewModels
Language = (int)config.System.Language.Value; Language = (int)config.System.Language.Value;
TimeZone = config.System.TimeZone; TimeZone = config.System.TimeZone;
DateTime dateTimeOffset = DateTime.Now.AddSeconds(config.System.SystemTimeOffset); DateTime currentDateTime = DateTime.Now;
CurrentDate = currentDateTime.Date;
CurrentTime = currentDateTime.TimeOfDay.Add(TimeSpan.FromSeconds(config.System.SystemTimeOffset));
DateOffset = dateTimeOffset.Date;
TimeOffset = dateTimeOffset.TimeOfDay;
EnableVsync = config.Graphics.EnableVsync; EnableVsync = config.Graphics.EnableVsync;
EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks; EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks;
ExpandDramSize = config.System.ExpandRam; ExpandDramSize = config.System.ExpandRam;
@@ -487,9 +489,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.System.TimeZone.Value = TimeZone; config.System.TimeZone.Value = TimeZone;
} }
TimeSpan systemTimeOffset = DateOffset - DateTime.Now; config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds());
config.System.SystemTimeOffset.Value = systemTimeOffset.Seconds;
config.Graphics.EnableVsync.Value = EnableVsync; config.Graphics.EnableVsync.Value = EnableVsync;
config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks; config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks;
config.System.ExpandRam.Value = ExpandDramSize; config.System.ExpandRam.Value = ExpandDramSize;

View File

@@ -3,12 +3,12 @@
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
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:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d"
x:CompileBindings="True" x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel"> x:DataType="viewModels:SettingsViewModel"
mc:Ignorable="d">
<Design.DataContext> <Design.DataContext>
<viewModels:SettingsViewModel /> <viewModels:SettingsViewModel />
</Design.DataContext> </Design.DataContext>
@@ -27,13 +27,15 @@
<TextBlock Classes="h1" Text="{locale:Locale SettingsTabSystemCore}" /> <TextBlock Classes="h1" Text="{locale:Locale SettingsTabSystemCore}" />
<StackPanel Margin="10,0,0,0" Orientation="Vertical"> <StackPanel Margin="10,0,0,0" Orientation="Vertical">
<StackPanel Margin="0,0,0,10" Orientation="Horizontal"> <StackPanel Margin="0,0,0,10" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" <TextBlock
Text="{locale:Locale SettingsTabSystemSystemRegion}" Width="250"
Width="250" /> VerticalAlignment="Center"
<ComboBox SelectedIndex="{Binding Region}" Text="{locale:Locale SettingsTabSystemSystemRegion}" />
ToolTip.Tip="{locale:Locale RegionTooltip}" <ComboBox
HorizontalContentAlignment="Left" Width="350"
Width="350"> HorizontalContentAlignment="Left"
SelectedIndex="{Binding Region}"
ToolTip.Tip="{locale:Locale RegionTooltip}">
<ComboBoxItem> <ComboBoxItem>
<TextBlock Text="{locale:Locale SettingsTabSystemSystemRegionJapan}" /> <TextBlock Text="{locale:Locale SettingsTabSystemSystemRegionJapan}" />
</ComboBoxItem> </ComboBoxItem>
@@ -58,20 +60,21 @@
</ComboBox> </ComboBox>
</StackPanel> </StackPanel>
<StackPanel Margin="0,0,0,10" Orientation="Horizontal"> <StackPanel Margin="0,0,0,10" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" <TextBlock
Text="{locale:Locale SettingsTabSystemSystemLanguage}" Width="250"
ToolTip.Tip="{locale:Locale LanguageTooltip}" VerticalAlignment="Center"
Width="250" /> Text="{locale:Locale SettingsTabSystemSystemLanguage}"
<ComboBox SelectedIndex="{Binding Language}" ToolTip.Tip="{locale:Locale LanguageTooltip}" />
ToolTip.Tip="{locale:Locale LanguageTooltip}" <ComboBox
HorizontalContentAlignment="Left" Width="350"
Width="350"> HorizontalContentAlignment="Left"
SelectedIndex="{Binding Language}"
ToolTip.Tip="{locale:Locale LanguageTooltip}">
<ComboBoxItem> <ComboBoxItem>
<TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageJapanese}" /> <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageJapanese}" />
</ComboBoxItem> </ComboBoxItem>
<ComboBoxItem> <ComboBoxItem>
<TextBlock <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageAmericanEnglish}" />
Text="{locale:Locale SettingsTabSystemSystemLanguageAmericanEnglish}" />
</ComboBoxItem> </ComboBoxItem>
<ComboBoxItem> <ComboBoxItem>
<TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageFrench}" /> <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageFrench}" />
@@ -104,71 +107,67 @@
<TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageTaiwanese}" /> <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageTaiwanese}" />
</ComboBoxItem> </ComboBoxItem>
<ComboBoxItem> <ComboBoxItem>
<TextBlock <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageBritishEnglish}" />
Text="{locale:Locale SettingsTabSystemSystemLanguageBritishEnglish}" />
</ComboBoxItem> </ComboBoxItem>
<ComboBoxItem> <ComboBoxItem>
<TextBlock <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageCanadianFrench}" />
Text="{locale:Locale SettingsTabSystemSystemLanguageCanadianFrench}" />
</ComboBoxItem> </ComboBoxItem>
<ComboBoxItem> <ComboBoxItem>
<TextBlock <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageLatinAmericanSpanish}" />
Text="{locale:Locale SettingsTabSystemSystemLanguageLatinAmericanSpanish}" />
</ComboBoxItem> </ComboBoxItem>
<ComboBoxItem> <ComboBoxItem>
<TextBlock <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageSimplifiedChinese}" />
Text="{locale:Locale SettingsTabSystemSystemLanguageSimplifiedChinese}" />
</ComboBoxItem> </ComboBoxItem>
<ComboBoxItem> <ComboBoxItem>
<TextBlock <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageTraditionalChinese}" />
Text="{locale:Locale SettingsTabSystemSystemLanguageTraditionalChinese}" />
</ComboBoxItem> </ComboBoxItem>
<ComboBoxItem> <ComboBoxItem>
<TextBlock <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageBrazilianPortuguese}" />
Text="{locale:Locale SettingsTabSystemSystemLanguageBrazilianPortuguese}" />
</ComboBoxItem> </ComboBoxItem>
</ComboBox> </ComboBox>
</StackPanel> </StackPanel>
<StackPanel Margin="0,0,0,10" Orientation="Horizontal"> <StackPanel Margin="0,0,0,10" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" <TextBlock
Text="{locale:Locale SettingsTabSystemSystemTimeZone}" Width="250"
ToolTip.Tip="{locale:Locale TimezoneTooltip}" VerticalAlignment="Center"
Width="250" /> Text="{locale:Locale SettingsTabSystemSystemTimeZone}"
ToolTip.Tip="{locale:Locale TimezoneTooltip}" />
<AutoCompleteBox <AutoCompleteBox
Name="TimeZoneBox" Name="TimeZoneBox"
Width="350" Width="350"
MaxDropDownHeight="500"
FilterMode="Contains" FilterMode="Contains"
Items="{Binding TimeZones}" Items="{Binding TimeZones}"
MaxDropDownHeight="500"
SelectionChanged="TimeZoneBox_OnSelectionChanged" SelectionChanged="TimeZoneBox_OnSelectionChanged"
Text="{Binding Path=TimeZone, Mode=OneWay}" Text="{Binding Path=TimeZone, Mode=OneWay}"
TextChanged="TimeZoneBox_OnTextChanged" TextChanged="TimeZoneBox_OnTextChanged"
ToolTip.Tip="{locale:Locale TimezoneTooltip}" /> ToolTip.Tip="{locale:Locale TimezoneTooltip}" />
</StackPanel> </StackPanel>
<StackPanel Margin="0,0,0,10" Orientation="Horizontal"> <StackPanel Margin="0,0,0,10" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" <TextBlock
Text="{locale:Locale SettingsTabSystemSystemTime}" Width="250"
ToolTip.Tip="{locale:Locale TimeTooltip}" VerticalAlignment="Center"
Width="250"/> Text="{locale:Locale SettingsTabSystemSystemTime}"
<DatePicker VerticalAlignment="Center" SelectedDate="{Binding DateOffset}" ToolTip.Tip="{locale:Locale TimeTooltip}" />
ToolTip.Tip="{locale:Locale TimeTooltip}" <DatePicker
Width="350" /> Width="350"
VerticalAlignment="Center"
SelectedDate="{Binding CurrentDate}"
ToolTip.Tip="{locale:Locale TimeTooltip}" />
</StackPanel> </StackPanel>
<StackPanel Margin="250,0,0,10" Orientation="Horizontal"> <StackPanel Margin="250,0,0,10" Orientation="Horizontal">
<TimePicker <TimePicker
Width="350"
VerticalAlignment="Center" VerticalAlignment="Center"
ClockIdentifier="24HourClock" ClockIdentifier="24HourClock"
SelectedTime="{Binding TimeOffset}" SelectedTime="{Binding CurrentTime}"
Width="350"
ToolTip.Tip="{locale:Locale TimeTooltip}" /> ToolTip.Tip="{locale:Locale TimeTooltip}" />
</StackPanel> </StackPanel>
<CheckBox IsChecked="{Binding EnableVsync}"> <CheckBox IsChecked="{Binding EnableVsync}">
<TextBlock Text="{locale:Locale SettingsTabSystemEnableVsync}" <TextBlock Text="{locale:Locale SettingsTabSystemEnableVsync}" ToolTip.Tip="{locale:Locale VSyncToggleTooltip}" />
ToolTip.Tip="{locale:Locale VSyncToggleTooltip}" />
</CheckBox> </CheckBox>
<CheckBox IsChecked="{Binding EnableFsIntegrityChecks}"> <CheckBox IsChecked="{Binding EnableFsIntegrityChecks}">
<TextBlock Text="{locale:Locale SettingsTabSystemEnableFsIntegrityChecks}" <TextBlock Text="{locale:Locale SettingsTabSystemEnableFsIntegrityChecks}" ToolTip.Tip="{locale:Locale FsIntegrityToggleTooltip}" />
ToolTip.Tip="{locale:Locale FsIntegrityToggleTooltip}" />
</CheckBox> </CheckBox>
</StackPanel> </StackPanel>
<Separator Height="1" /> <Separator Height="1" />
@@ -180,12 +179,10 @@
Margin="10,0,0,0" Margin="10,0,0,0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Orientation="Vertical"> Orientation="Vertical">
<CheckBox IsChecked="{Binding ExpandDramSize}" <CheckBox IsChecked="{Binding ExpandDramSize}" ToolTip.Tip="{locale:Locale DRamTooltip}">
ToolTip.Tip="{locale:Locale DRamTooltip}">
<TextBlock Text="{locale:Locale SettingsTabSystemExpandDramSize}" /> <TextBlock Text="{locale:Locale SettingsTabSystemExpandDramSize}" />
</CheckBox> </CheckBox>
<CheckBox IsChecked="{Binding IgnoreMissingServices}" <CheckBox IsChecked="{Binding IgnoreMissingServices}" ToolTip.Tip="{locale:Locale IgnoreMissingServicesTooltip}">
ToolTip.Tip="{locale:Locale IgnoreMissingServicesTooltip}">
<TextBlock Text="{locale:Locale SettingsTabSystemIgnoreMissingServices}" /> <TextBlock Text="{locale:Locale SettingsTabSystemIgnoreMissingServices}" />
</CheckBox> </CheckBox>
</StackPanel> </StackPanel>

View File

@@ -66,6 +66,8 @@ namespace Ryujinx.Graphics.Vulkan
private ulong _vertexBuffersDirty; private ulong _vertexBuffersDirty;
protected Rectangle<int> ClearScissor; protected Rectangle<int> ClearScissor;
private readonly VertexBufferUpdater _vertexBufferUpdater;
public SupportBufferUpdater SupportBufferUpdater; public SupportBufferUpdater SupportBufferUpdater;
public IndexBufferPattern QuadsToTrisPattern; public IndexBufferPattern QuadsToTrisPattern;
public IndexBufferPattern TriFanToTrisPattern; public IndexBufferPattern TriFanToTrisPattern;
@@ -96,6 +98,7 @@ namespace Ryujinx.Graphics.Vulkan
gd.Api.CreatePipelineCache(device, pipelineCacheCreateInfo, null, out PipelineCache).ThrowOnError(); gd.Api.CreatePipelineCache(device, pipelineCacheCreateInfo, null, out PipelineCache).ThrowOnError();
_descriptorSetUpdater = new DescriptorSetUpdater(gd, this); _descriptorSetUpdater = new DescriptorSetUpdater(gd, this);
_vertexBufferUpdater = new VertexBufferUpdater(gd);
_transformFeedbackBuffers = new BufferState[Constants.MaxTransformFeedbackBuffers]; _transformFeedbackBuffers = new BufferState[Constants.MaxTransformFeedbackBuffers];
_vertexBuffers = new VertexBufferState[Constants.MaxVertexBuffers + 1]; _vertexBuffers = new VertexBufferState[Constants.MaxVertexBuffers + 1];
@@ -1185,6 +1188,9 @@ namespace Ryujinx.Graphics.Vulkan
int validCount = 1; int validCount = 1;
BufferHandle lastHandle = default;
Auto<DisposableBuffer> lastBuffer = default;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
var vertexBuffer = vertexBuffers[i]; var vertexBuffer = vertexBuffers[i];
@@ -1194,7 +1200,12 @@ namespace Ryujinx.Graphics.Vulkan
if (vertexBuffer.Buffer.Handle != BufferHandle.Null) if (vertexBuffer.Buffer.Handle != BufferHandle.Null)
{ {
var vb = Gd.BufferManager.GetBuffer(CommandBuffer, vertexBuffer.Buffer.Handle, false); Auto<DisposableBuffer> vb = (vertexBuffer.Buffer.Handle == lastHandle) ? lastBuffer :
Gd.BufferManager.GetBuffer(CommandBuffer, vertexBuffer.Buffer.Handle, false);
lastHandle = vertexBuffer.Buffer.Handle;
lastBuffer = vb;
if (vb != null) if (vb != null)
{ {
int binding = i + 1; int binding = i + 1;
@@ -1222,24 +1233,29 @@ namespace Ryujinx.Graphics.Vulkan
ref var buffer = ref _vertexBuffers[binding]; ref var buffer = ref _vertexBuffers[binding];
int oldScalarAlign = buffer.AttributeScalarAlignment; int oldScalarAlign = buffer.AttributeScalarAlignment;
buffer.Dispose();
if (Gd.Capabilities.VertexBufferAlignment < 2 && if (Gd.Capabilities.VertexBufferAlignment < 2 &&
(vertexBuffer.Stride % FormatExtensions.MaxBufferFormatScalarSize) == 0) (vertexBuffer.Stride % FormatExtensions.MaxBufferFormatScalarSize) == 0)
{ {
buffer = new VertexBufferState( if (!buffer.Matches(vb, descriptorIndex, vertexBuffer.Buffer.Offset, vbSize, vertexBuffer.Stride))
vb, {
descriptorIndex, buffer.Dispose();
vertexBuffer.Buffer.Offset,
vbSize,
vertexBuffer.Stride);
buffer.BindVertexBuffer(Gd, Cbs, (uint)binding, ref _newState); buffer = new VertexBufferState(
vb,
descriptorIndex,
vertexBuffer.Buffer.Offset,
vbSize,
vertexBuffer.Stride);
buffer.BindVertexBuffer(Gd, Cbs, (uint)binding, ref _newState, _vertexBufferUpdater);
}
} }
else else
{ {
// May need to be rewritten. Bind this buffer before draw. // May need to be rewritten. Bind this buffer before draw.
buffer.Dispose();
buffer = new VertexBufferState( buffer = new VertexBufferState(
vertexBuffer.Buffer.Handle, vertexBuffer.Buffer.Handle,
descriptorIndex, descriptorIndex,
@@ -1255,6 +1271,8 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
_vertexBufferUpdater.Commit(Cbs);
_newState.VertexBindingDescriptionsCount = (uint)validCount; _newState.VertexBindingDescriptionsCount = (uint)validCount;
SignalStateChange(); SignalStateChange();
} }
@@ -1596,10 +1614,12 @@ namespace Ryujinx.Graphics.Vulkan
{ {
int i = BitOperations.TrailingZeroCount(_vertexBuffersDirty); int i = BitOperations.TrailingZeroCount(_vertexBuffersDirty);
_vertexBuffers[i].BindVertexBuffer(Gd, Cbs, (uint)i, ref _newState); _vertexBuffers[i].BindVertexBuffer(Gd, Cbs, (uint)i, ref _newState, _vertexBufferUpdater);
_vertexBuffersDirty &= ~(1UL << i); _vertexBuffersDirty &= ~(1UL << i);
} }
_vertexBufferUpdater.Commit(Cbs);
} }
if (_stateDirty || Pbp != pbp) if (_stateDirty || Pbp != pbp)
@@ -1712,6 +1732,7 @@ namespace Ryujinx.Graphics.Vulkan
_framebuffer?.Dispose(); _framebuffer?.Dispose();
_newState.Dispose(); _newState.Dispose();
_descriptorSetUpdater.Dispose(); _descriptorSetUpdater.Dispose();
_vertexBufferUpdater.Dispose();
for (int i = 0; i < _vertexBuffers.Length; i++) for (int i = 0; i < _vertexBuffers.Length; i++)
{ {

View File

@@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Vulkan
AttributeScalarAlignment = 1; AttributeScalarAlignment = 1;
} }
public void BindVertexBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding, ref PipelineState state) public void BindVertexBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding, ref PipelineState state, VertexBufferUpdater updater)
{ {
var autoBuffer = _buffer; var autoBuffer = _buffer;
@@ -65,21 +65,7 @@ namespace Ryujinx.Graphics.Vulkan
var buffer = autoBuffer.Get(cbs, 0, newSize).Value; var buffer = autoBuffer.Get(cbs, 0, newSize).Value;
if (gd.Capabilities.SupportsExtendedDynamicState) updater.BindVertexBuffer(cbs, binding, buffer, 0, (ulong)newSize, (ulong)stride);
{
gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2(
cbs.CommandBuffer,
binding,
1,
buffer,
0,
(ulong)newSize,
(ulong)stride);
}
else
{
gd.Api.CmdBindVertexBuffers(cbs.CommandBuffer, binding, 1, buffer, 0);
}
_buffer = autoBuffer; _buffer = autoBuffer;
@@ -106,21 +92,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
var buffer = autoBuffer.Get(cbs, _offset, _size).Value; var buffer = autoBuffer.Get(cbs, _offset, _size).Value;
if (gd.Capabilities.SupportsExtendedDynamicState) updater.BindVertexBuffer(cbs, binding, buffer, (ulong)_offset, (ulong)_size, (ulong)_stride);
{
gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2(
cbs.CommandBuffer,
binding,
1,
buffer,
(ulong)_offset,
(ulong)_size,
(ulong)_stride);
}
else
{
gd.Api.CmdBindVertexBuffers(cbs.CommandBuffer, binding, 1, buffer, (ulong)_offset);
}
} }
} }
@@ -129,6 +101,11 @@ namespace Ryujinx.Graphics.Vulkan
return _buffer == buffer; return _buffer == buffer;
} }
public bool Matches(Auto<DisposableBuffer> buffer, int descriptorIndex, int offset, int size, int stride = 0)
{
return _buffer == buffer && DescriptorIndex == descriptorIndex && _offset == offset && _size == size && _stride == stride;
}
public void Swap(Auto<DisposableBuffer> from, Auto<DisposableBuffer> to) public void Swap(Auto<DisposableBuffer> from, Auto<DisposableBuffer> to)
{ {
if (_buffer == from) if (_buffer == from)

View File

@@ -0,0 +1,84 @@
using Silk.NET.Vulkan;
using System;
using VkBuffer = Silk.NET.Vulkan.Buffer;
namespace Ryujinx.Graphics.Vulkan
{
internal class VertexBufferUpdater : IDisposable
{
private VulkanRenderer _gd;
private uint _baseBinding;
private uint _count;
private NativeArray<VkBuffer> _buffers;
private NativeArray<ulong> _offsets;
private NativeArray<ulong> _sizes;
private NativeArray<ulong> _strides;
public VertexBufferUpdater(VulkanRenderer gd)
{
_gd = gd;
_buffers = new NativeArray<VkBuffer>(Constants.MaxVertexBuffers);
_offsets = new NativeArray<ulong>(Constants.MaxVertexBuffers);
_sizes = new NativeArray<ulong>(Constants.MaxVertexBuffers);
_strides = new NativeArray<ulong>(Constants.MaxVertexBuffers);
}
public void BindVertexBuffer(CommandBufferScoped cbs, uint binding, VkBuffer buffer, ulong offset, ulong size, ulong stride)
{
if (_count == 0)
{
_baseBinding = binding;
}
else if (_baseBinding + _count != binding)
{
Commit(cbs);
_baseBinding = binding;
}
int index = (int)_count;
_buffers[index] = buffer;
_offsets[index] = offset;
_sizes[index] = size;
_strides[index] = stride;
_count++;
}
public unsafe void Commit(CommandBufferScoped cbs)
{
if (_count != 0)
{
if (_gd.Capabilities.SupportsExtendedDynamicState)
{
_gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2(
cbs.CommandBuffer,
_baseBinding,
_count,
_buffers.Pointer,
_offsets.Pointer,
_sizes.Pointer,
_strides.Pointer);
}
else
{
_gd.Api.CmdBindVertexBuffers(cbs.CommandBuffer, _baseBinding, _count, _buffers.Pointer, _offsets.Pointer);
}
_count = 0;
}
}
public void Dispose()
{
_buffers.Dispose();
_offsets.Dispose();
_sizes.Dispose();
_strides.Dispose();
}
}
}

View File

@@ -116,7 +116,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
device, device,
device.System.KernelContext, device.System.KernelContext,
metaLoader, metaLoader,
nacpData.Value, nacpData,
enablePtc, enablePtc,
allowCodeMemoryForJit, allowCodeMemoryForJit,
programName, programName,

View File

@@ -209,7 +209,7 @@ namespace Ryujinx.HLE.Loaders.Processes
ProcessResult processResult = ProcessLoaderHelper.LoadNsos(_device, ProcessResult processResult = ProcessLoaderHelper.LoadNsos(_device,
_device.System.KernelContext, _device.System.KernelContext,
dummyExeFs.GetNpdm(), dummyExeFs.GetNpdm(),
nacpData.Value, nacpData,
diskCacheEnabled: false, diskCacheEnabled: false,
allowCodeMemoryForJit: true, allowCodeMemoryForJit: true,
programName, programName,

View File

@@ -219,7 +219,7 @@ namespace Ryujinx.HLE.Loaders.Processes
Switch device, Switch device,
KernelContext context, KernelContext context,
MetaLoader metaLoader, MetaLoader metaLoader,
ApplicationControlProperty applicationControlProperties, BlitStruct<ApplicationControlProperty> applicationControlProperties,
bool diskCacheEnabled, bool diskCacheEnabled,
bool allowCodeMemoryForJit, bool allowCodeMemoryForJit,
string name, string name,
@@ -355,7 +355,7 @@ namespace Ryujinx.HLE.Loaders.Processes
context.Device.System.TickSource, context.Device.System.TickSource,
context.Device.Gpu, context.Device.Gpu,
$"{programId:x16}", $"{programId:x16}",
applicationControlProperties.DisplayVersionString.ToString(), applicationControlProperties.Value.DisplayVersionString.ToString(),
diskCacheEnabled, diskCacheEnabled,
codeStart, codeStart,
codeSize); codeSize);

View File

@@ -1,4 +1,5 @@
using LibHac.Loader; using LibHac.Common;
using LibHac.Loader;
using LibHac.Ns; using LibHac.Ns;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Cpu; using Ryujinx.Cpu;
@@ -11,7 +12,7 @@ namespace Ryujinx.HLE.Loaders.Processes
{ {
public class ProcessResult public class ProcessResult
{ {
public static ProcessResult Failed => new(null, new ApplicationControlProperty(), false, false, null, 0, 0, 0, TitleLanguage.AmericanEnglish); public static ProcessResult Failed => new(null, new BlitStruct<ApplicationControlProperty>(1), false, false, null, 0, 0, 0, TitleLanguage.AmericanEnglish);
private readonly byte _mainThreadPriority; private readonly byte _mainThreadPriority;
private readonly uint _mainThreadStackSize; private readonly uint _mainThreadStackSize;
@@ -31,15 +32,15 @@ namespace Ryujinx.HLE.Loaders.Processes
public readonly bool AllowCodeMemoryForJit; public readonly bool AllowCodeMemoryForJit;
public ProcessResult( public ProcessResult(
MetaLoader metaLoader, MetaLoader metaLoader,
ApplicationControlProperty applicationControlProperties, BlitStruct<ApplicationControlProperty> applicationControlProperties,
bool diskCacheEnabled, bool diskCacheEnabled,
bool allowCodeMemoryForJit, bool allowCodeMemoryForJit,
IDiskCacheLoadState diskCacheLoadState, IDiskCacheLoadState diskCacheLoadState,
ulong pid, ulong pid,
byte mainThreadPriority, byte mainThreadPriority,
uint mainThreadStackSize, uint mainThreadStackSize,
TitleLanguage titleLanguage) TitleLanguage titleLanguage)
{ {
_mainThreadPriority = mainThreadPriority; _mainThreadPriority = mainThreadPriority;
_mainThreadStackSize = mainThreadStackSize; _mainThreadStackSize = mainThreadStackSize;
@@ -48,7 +49,7 @@ namespace Ryujinx.HLE.Loaders.Processes
ProcessId = pid; ProcessId = pid;
MetaLoader = metaLoader; MetaLoader = metaLoader;
ApplicationControlProperties = applicationControlProperties; ApplicationControlProperties = applicationControlProperties.Value;
if (metaLoader is not null) if (metaLoader is not null)
{ {