Compare commits

...

7 Commits

Author SHA1 Message Date
gdkchan
599d485bff Change NvMap ID allocation to match nvservices (#3741)
* Change NvMap ID allocation to match nvservices

* Move NvMapIdDictionary to Types
2022-10-05 17:49:18 -03:00
gdkchan
60e16c15b6 Fix memory corruption in BCAT and FS Read methods when buffer is larger than needed (#3739)
* Fix memory corruption in FS Read methods when buffer is larger than needed

* PR feedback

* nit: Don't move this around
2022-10-04 20:12:54 -03:00
gdkchan
2068445939 Fix shader SULD (bindless) instruction using wrong register as handle (#3732)
* GLSL: Do not generate scale helpers if we have no textures

* Fix shader SULD (bindless) instruction using wrong register as handle
2022-10-03 20:40:22 -03:00
gdkchan
a4fc9f8050 Support use of buffer ranges with size 0 (#3736) 2022-10-03 20:08:38 -03:00
gdkchan
5437d6cb13 Vulkan: Fix buffer texture storage not being updated on buffer handle reuse (#3731) 2022-10-03 19:45:33 -03:00
Emmanuel Hansen
7539e26144 Avalonia - Fixes updater (#3670)
* update avalonia

* fix updater

* fix spacing

* addressed review

* convert permission value to octal

* Add missing comma

* revert package updates
2022-10-03 11:25:25 -03:00
Luna
1c3697b6a4 Update AboutWindow.axaml (#3724) 2022-10-02 22:02:11 +00:00
24 changed files with 266 additions and 298 deletions

View File

@@ -574,12 +574,12 @@
"Discard": "Discard",
"UserProfilesSetProfileImage": "Set Profile Image",
"UserProfileEmptyNameError": "Name is required",
"UserProfileNoImageError": "Profile image must be set",
"UserProfileNoImageError": "Profile image must be set",
"GameUpdateWindowHeading": "Updates Available for {0} [{1}]",
"SettingsTabHotkeysResScaleUpHotkey": "Increase resolution:",
"SettingsTabHotkeysResScaleDownHotkey": "Decrease resolution:",
"UserProfilesName": "Name:",
"UserProfilesUserId" : "User Id:",
"UserProfilesUserId": "User Id:",
"SettingsTabGraphicsBackend": "Graphics Backend",
"SettingsTabGraphicsBackendTooltip": "Graphics Backend to use",
"SettingsEnableTextureRecompression": "Enable Texture Recompression",
@@ -589,6 +589,7 @@
"SettingsAppRequiredRestartMessage": "Ryujinx Restart Required",
"SettingsGpuBackendRestartMessage": "Graphics Backend or Gpu settings have been modified. This will require a restart to be applied",
"SettingsGpuBackendRestartSubMessage": "Do you want to restart now?",
"RyujinxUpdaterMessage": "Do you want to update Ryujinx to the latest version?",
"SettingsTabHotkeysVolumeUpHotkey": "Increase Volume:",
"SettingsTabHotkeysVolumeDownHotkey": "Decrease Volume:",
"VolumeShort": "Vol"

View File

@@ -1,4 +1,6 @@
using Avalonia.Controls;
using Avalonia.Threading;
using FluentAvalonia.UI.Controls;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
using ICSharpCode.SharpZipLib.Zip;
@@ -11,11 +13,13 @@ using Ryujinx.Common;
using Ryujinx.Common.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
@@ -40,6 +44,8 @@ namespace Ryujinx.Modules
private static readonly string[] WindowsDependencyDirs = Array.Empty<string>();
public static bool UpdateSuccessful { get; private set; }
public static async Task BeginParse(MainWindow mainWindow, bool showVersionUpToDate)
{
if (Running)
@@ -198,11 +204,18 @@ namespace Ryujinx.Modules
_buildSize = -1;
}
}
Dispatcher.UIThread.Post(async () =>
{
// Show a message asking the user if they want to update
UpdaterWindow updateDialog = new(mainWindow, newVersion, _buildUrl);
await updateDialog.ShowDialog(mainWindow);
var shouldUpdate = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance["RyujinxUpdater"],
LocaleManager.Instance["RyujinxUpdaterMessage"],
$"{Program.Version} -> {newVersion}");
if (shouldUpdate)
{
UpdateRyujinx(mainWindow, _buildUrl);
}
});
}
@@ -216,8 +229,10 @@ namespace Ryujinx.Modules
return result;
}
public static void UpdateRyujinx(UpdaterWindow updateDialog, string downloadUrl)
public static async void UpdateRyujinx(Window parent, string downloadUrl)
{
UpdateSuccessful = false;
// Empty update dir, although it shouldn't ever have anything inside it
if (Directory.Exists(UpdateDir))
{
@@ -228,25 +243,56 @@ namespace Ryujinx.Modules
string updateFile = Path.Combine(UpdateDir, "update.bin");
// Download the update .zip
updateDialog.MainText.Text = LocaleManager.Instance["UpdaterDownloading"];
updateDialog.ProgressBar.Value = 0;
updateDialog.ProgressBar.Maximum = 100;
var taskDialog = new TaskDialog()
{
Header = LocaleManager.Instance["RyujinxUpdater"],
SubHeader = LocaleManager.Instance["UpdaterDownloading"],
IconSource = new SymbolIconSource { Symbol = Symbol.Download },
Buttons = { },
ShowProgressBar = true
};
Task.Run(() =>
taskDialog.XamlRoot = parent;
taskDialog.Opened += (s, e) =>
{
if (_buildSize >= 0)
{
DoUpdateWithMultipleThreads(updateDialog, downloadUrl, updateFile);
DoUpdateWithMultipleThreads(taskDialog, downloadUrl, updateFile);
}
else
{
DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
}
});
};
await taskDialog.ShowAsync(true);
if (UpdateSuccessful)
{
var shouldRestart = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance["RyujinxUpdater"],
LocaleManager.Instance["DialogUpdaterCompleteMessage"],
LocaleManager.Instance["DialogUpdaterRestartMessage"]);
if (shouldRestart)
{
string ryuName = Path.GetFileName(Environment.ProcessPath);
string ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
string ryuArg = string.Join(" ", Environment.GetCommandLineArgs().Skip(1).ToArray());
if (!OperatingSystem.IsWindows())
{
chmod(ryuExe, Convert.ToUInt32("0777", 8));
}
Process.Start(ryuExe, ryuArg);
Environment.Exit(0);
}
}
}
private static void DoUpdateWithMultipleThreads(UpdaterWindow updateDialog, string downloadUrl, string updateFile)
private static void DoUpdateWithMultipleThreads(TaskDialog taskDialog, string downloadUrl, string updateFile)
{
// Multi-Threaded Updater
long chunkSize = _buildSize / ConnectionCount;
@@ -290,7 +336,7 @@ namespace Ryujinx.Modules
Interlocked.Exchange(ref progressPercentage[index], args.ProgressPercentage);
Interlocked.Add(ref totalProgressPercentage, args.ProgressPercentage);
updateDialog.ProgressBar.Value = totalProgressPercentage / ConnectionCount;
taskDialog.SetProgressBarState(totalProgressPercentage / ConnectionCount, TaskDialogProgressState.Normal);
};
client.DownloadDataCompleted += (_, args) =>
@@ -301,6 +347,8 @@ namespace Ryujinx.Modules
{
webClients[index].Dispose();
taskDialog.Hide();
return;
}
@@ -320,14 +368,14 @@ namespace Ryujinx.Modules
try
{
InstallUpdate(updateDialog, updateFile);
InstallUpdate(taskDialog, updateFile);
}
catch (Exception e)
{
Logger.Warning?.Print(LogClass.Application, e.Message);
Logger.Warning?.Print(LogClass.Application, "Multi-Threaded update failed, falling back to single-threaded updater.");
DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
return;
}
@@ -348,7 +396,7 @@ namespace Ryujinx.Modules
webClients[j].CancelAsync();
}
DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
return;
}
@@ -356,7 +404,7 @@ namespace Ryujinx.Modules
}
}
private static void DoUpdateWithSingleThreadWorker(UpdaterWindow updateDialog, string downloadUrl, string updateFile)
private static void DoUpdateWithSingleThreadWorker(TaskDialog taskDialog, string downloadUrl, string updateFile)
{
using (HttpClient client = new HttpClient())
{
@@ -384,19 +432,26 @@ namespace Ryujinx.Modules
byteWritten += readSize;
updateDialog.ProgressBar.Value = ((double)byteWritten / totalBytes) * 100;
taskDialog.SetProgressBarState(GetPercentage(byteWritten, totalBytes), TaskDialogProgressState.Normal);
updateFileStream.Write(buffer, 0, readSize);
}
}
}
InstallUpdate(updateDialog, updateFile);
InstallUpdate(taskDialog, updateFile);
}
}
private static void DoUpdateWithSingleThread(UpdaterWindow updateDialog, string downloadUrl, string updateFile)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static double GetPercentage(double value, double max)
{
Thread worker = new Thread(() => DoUpdateWithSingleThreadWorker(updateDialog, downloadUrl, updateFile));
return max == 0 ? 0 : value / max * 100;
}
private static void DoUpdateWithSingleThread(TaskDialog taskDialog, string downloadUrl, string updateFile)
{
Thread worker = new Thread(() => DoUpdateWithSingleThreadWorker(taskDialog, downloadUrl, updateFile));
worker.Name = "Updater.SingleThreadWorker";
worker.Start();
}
@@ -414,11 +469,11 @@ namespace Ryujinx.Modules
}
}
private static async void InstallUpdate(UpdaterWindow updateDialog, string updateFile)
private static async void InstallUpdate(TaskDialog taskDialog, string updateFile)
{
// Extract Update
updateDialog.MainText.Text = LocaleManager.Instance["UpdaterExtracting"];
updateDialog.ProgressBar.Value = 0;
taskDialog.SubHeader = LocaleManager.Instance["UpdaterExtracting"];
taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
if (OperatingSystem.IsLinux())
{
@@ -426,8 +481,6 @@ namespace Ryujinx.Modules
using (Stream gzipStream = new GZipInputStream(inStream))
using (TarInputStream tarStream = new TarInputStream(gzipStream, Encoding.ASCII))
{
updateDialog.ProgressBar.Maximum = inStream.Length;
await Task.Run(() =>
{
TarEntry tarEntry;
@@ -450,12 +503,12 @@ namespace Ryujinx.Modules
Dispatcher.UIThread.Post(() =>
{
updateDialog.ProgressBar.Value += entry.Size;
taskDialog.SetProgressBarState(GetPercentage(entry.Size, inStream.Length), TaskDialogProgressState.Normal);
});
}
});
updateDialog.ProgressBar.Value = inStream.Length;
taskDialog.SetProgressBarState(100, TaskDialogProgressState.Normal);
}
}
else
@@ -463,12 +516,12 @@ namespace Ryujinx.Modules
using (Stream inStream = File.OpenRead(updateFile))
using (ZipFile zipFile = new ZipFile(inStream))
{
updateDialog.ProgressBar.Maximum = zipFile.Count;
await Task.Run(() =>
{
double count = 0;
foreach (ZipEntry zipEntry in zipFile)
{
count++;
if (zipEntry.IsDirectory) continue;
string outPath = Path.Combine(UpdateDir, zipEntry.Name);
@@ -485,7 +538,7 @@ namespace Ryujinx.Modules
Dispatcher.UIThread.Post(() =>
{
updateDialog.ProgressBar.Value++;
taskDialog.SetProgressBarState(GetPercentage(count, zipFile.Count), TaskDialogProgressState.Normal);
});
}
});
@@ -497,22 +550,23 @@ namespace Ryujinx.Modules
List<string> allFiles = EnumerateFilesToDelete().ToList();
updateDialog.MainText.Text = LocaleManager.Instance["UpdaterRenaming"];
updateDialog.ProgressBar.Value = 0;
updateDialog.ProgressBar.Maximum = allFiles.Count;
taskDialog.SubHeader = LocaleManager.Instance["UpdaterRenaming"];
taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
// Replace old files
await Task.Run(() =>
{
double count = 0;
foreach (string file in allFiles)
{
count++;
try
{
File.Move(file, file + ".ryuold");
Dispatcher.UIThread.Post(() =>
{
updateDialog.ProgressBar.Value++;
taskDialog.SetProgressBarState(GetPercentage(count, allFiles.Count), TaskDialogProgressState.Normal);
});
}
catch
@@ -523,23 +577,20 @@ namespace Ryujinx.Modules
Dispatcher.UIThread.Post(() =>
{
updateDialog.MainText.Text = LocaleManager.Instance["UpdaterAddingFiles"];
updateDialog.ProgressBar.Value = 0;
updateDialog.ProgressBar.Maximum = Directory.GetFiles(UpdatePublishDir, "*", SearchOption.AllDirectories).Length;
taskDialog.SubHeader = LocaleManager.Instance["UpdaterAddingFiles"];
taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
});
MoveAllFilesOver(UpdatePublishDir, HomeDir, updateDialog);
MoveAllFilesOver(UpdatePublishDir, HomeDir, taskDialog);
});
Directory.Delete(UpdateDir, true);
SetUnixPermissions();
updateDialog.MainText.Text = LocaleManager.Instance["DialogUpdaterCompleteMessage"];
updateDialog.SecondaryText.Text = LocaleManager.Instance["DialogUpdaterRestartMessage"];
UpdateSuccessful = true;
updateDialog.ProgressBar.IsVisible = false;
updateDialog.ButtonBox.IsVisible = true;
taskDialog.Hide();
}
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
@@ -618,8 +669,9 @@ namespace Ryujinx.Modules
return files;
}
private static void MoveAllFilesOver(string root, string dest, UpdaterWindow dialog)
private static void MoveAllFilesOver(string root, string dest, TaskDialog taskDialog)
{
var total = Directory.GetFiles(root, "*", SearchOption.AllDirectories).Length;
foreach (string directory in Directory.GetDirectories(root))
{
string dirName = Path.GetFileName(directory);
@@ -629,16 +681,18 @@ namespace Ryujinx.Modules
Directory.CreateDirectory(Path.Combine(dest, dirName));
}
MoveAllFilesOver(directory, Path.Combine(dest, dirName), dialog);
MoveAllFilesOver(directory, Path.Combine(dest, dirName), taskDialog);
}
double count = 0;
foreach (string file in Directory.GetFiles(root))
{
count++;
File.Move(file, Path.Combine(dest, Path.GetFileName(file)), true);
Dispatcher.UIThread.InvokeAsync(() =>
{
dialog.ProgressBar.Value++;
taskDialog.SetProgressBarState(GetPercentage(count, total), TaskDialogProgressState.Normal);
});
}
}

View File

@@ -6,7 +6,6 @@
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
Title="Ryujinx - About"
Width="850"
Height="550"
MinWidth="500"

View File

@@ -1,66 +0,0 @@
<window:StyleableWindow
x:Class="Ryujinx.Ava.Ui.Windows.UpdaterWindow"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
Title="Ryujinx Updater"
Width="500"
Height="500"
MinWidth="500"
MinHeight="500"
d:DesignHeight="350"
d:DesignWidth="400"
CanResize="False"
SizeToContent="Height"
WindowStartupLocation="CenterOwner"
mc:Ignorable="d">
<Grid
Margin="20"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock
Name="MainText"
Grid.Row="1"
Height="20"
HorizontalAlignment="Stretch"
TextAlignment="Center" />
<TextBlock
Name="SecondaryText"
Grid.Row="2"
Height="20"
HorizontalAlignment="Stretch"
TextAlignment="Center" />
<ProgressBar
Name="ProgressBar"
Grid.Row="3"
Margin="20"
HorizontalAlignment="Stretch"
IsVisible="False"
Maximum="100"
Minimum="0" />
<StackPanel
Name="ButtonBox"
Grid.Row="4"
HorizontalAlignment="Right"
IsVisible="False"
Orientation="Horizontal"
Spacing="20">
<Button MinWidth="50" Command="{Binding YesPressed}">
<TextBlock Text="{locale:Locale InputDialogYes}" TextAlignment="Center" />
</Button>
<Button MinWidth="50" Command="{Binding NoPressed}">
<TextBlock Text="{locale:Locale InputDialogNo}" TextAlignment="Center" />
</Button>
</StackPanel>
</Grid>
</window:StyleableWindow>

View File

@@ -1,73 +0,0 @@
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Modules;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace Ryujinx.Ava.Ui.Windows
{
public partial class UpdaterWindow : StyleableWindow
{
private readonly string _buildUrl;
private readonly MainWindow _mainWindow;
private readonly Version _newVersion;
private bool _restartQuery;
public UpdaterWindow()
{
DataContext = this;
InitializeComponent();
Title = LocaleManager.Instance["RyujinxUpdater"];
}
public UpdaterWindow(MainWindow mainWindow, Version newVersion, string buildUrl) : this()
{
_mainWindow = mainWindow;
_newVersion = newVersion;
_buildUrl = buildUrl;
}
[DllImport("libc", SetLastError = true)]
private static extern int chmod(string path, uint mode);
public void YesPressed()
{
if (_restartQuery)
{
string ryuName = OperatingSystem.IsWindows() ? "Ryujinx.Ava.exe" : "Ryujinx.Ava";
string ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
string ryuArg = string.Join(" ", Environment.GetCommandLineArgs().AsEnumerable().Skip(1).ToArray());
if (!OperatingSystem.IsWindows())
{
chmod(ryuExe, 0777);
}
Process.Start(ryuExe, ryuArg);
Environment.Exit(0);
}
else
{
ButtonBox.IsVisible = false;
ProgressBar.IsVisible = true;
SecondaryText.Text = "";
_restartQuery = true;
Updater.UpdateRyujinx(this, _buildUrl);
}
}
public void NoPressed()
{
_mainWindow.UpdateMenuItem.IsEnabled = true;
Close();
}
}
}

View File

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

View File

@@ -257,7 +257,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
DeclareSupportUniformBlock(context, context.Config.Stage, scaleElements);
if (context.Config.UsedFeatures.HasFlag(FeatureFlags.IntegerSampling))
if (context.Config.UsedFeatures.HasFlag(FeatureFlags.IntegerSampling) && scaleElements != 0)
{
AppendHelperFunction(context, $"Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_{stage}.glsl");
context.AppendLine();

View File

@@ -279,16 +279,16 @@ namespace Ryujinx.Graphics.Shader.Decoders
Add("1110101110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuatomB2, InstEmit.SuatomB2, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc);
Add("1110101011010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuatomCasB, InstEmit.SuatomCasB, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.Rc | InstProps.SPd);
Add("1110101x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuatomCas, InstEmit.SuatomCas, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.SPd);
Add("111010110001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldDB, InstEmit.SuldDB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.SPd | InstProps.TexB);
Add("1110101100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldDB, InstEmit.SuldDB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.SPd | InstProps.TexB);
Add("1110101100011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldD, InstEmit.SuldD, InstProps.Rd | InstProps.Ra | InstProps.SPd | InstProps.Tex);
Add("11101011000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldB, InstEmit.SuldB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.SPd | InstProps.TexB);
Add("11101011000x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Suld, InstEmit.Suld, InstProps.Rd | InstProps.Ra | InstProps.SPd | InstProps.Tex);
Add("111010110101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuredB, InstEmit.SuredB, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("1110101100000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldB, InstEmit.SuldB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.SPd | InstProps.TexB);
Add("1110101100001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Suld, InstEmit.Suld, InstProps.Rd | InstProps.Ra | InstProps.SPd | InstProps.Tex);
Add("1110101101010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuredB, InstEmit.SuredB, InstProps.Rd | InstProps.Ra | InstProps.Rc);
Add("1110101101011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sured, InstEmit.Sured, InstProps.Rd | InstProps.Ra);
Add("111010110011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SustDB, InstEmit.SustDB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.TexB);
Add("1110101100110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SustDB, InstEmit.SustDB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.TexB);
Add("1110101100111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SustD, InstEmit.SustD, InstProps.Rd | InstProps.Ra | InstProps.Tex);
Add("11101011001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SustB, InstEmit.SustB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.TexB);
Add("11101011001x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sust, InstEmit.Sust, InstProps.Rd | InstProps.Ra | InstProps.Tex);
Add("1110101100100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SustB, InstEmit.SustB, InstProps.Rd | InstProps.Ra | InstProps.Rc | InstProps.TexB);
Add("1110101100101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sust, InstEmit.Sust, InstProps.Rd | InstProps.Ra | InstProps.Tex);
Add("1111000011111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sync, InstEmit.Sync, InstProps.Bra);
Add("11000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tex, InstEmit.Tex, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.TPd | InstProps.Tex);
Add("1101111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TexB, InstEmit.TexB, InstProps.Rd | InstProps.Ra | InstProps.Rb | InstProps.TPd | InstProps.TexB);

View File

@@ -123,7 +123,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
InstSuldB op = context.GetOp<InstSuldB>();
EmitSuld(context, op.CacheOp, op.Dim, 0, 0, op.Rgba, op.SrcA, op.Dest, 0, useComponents: true, false, isBindless: true);
EmitSuld(context, op.CacheOp, op.Dim, 0, 0, op.Rgba, op.SrcA, op.Dest, op.SrcC, useComponents: true, false, isBindless: true);
}
public static void Suld(EmitterContext context)

View File

@@ -38,6 +38,8 @@ namespace Ryujinx.Graphics.Vulkan
private readonly IdList<BufferHolder> _buffers;
public int BufferCount { get; private set; }
public StagingBuffer StagingBuffer { get; }
public BufferManager(VulkanRenderer gd, PhysicalDevice physicalDevice, Device device)
@@ -56,6 +58,8 @@ namespace Ryujinx.Graphics.Vulkan
return BufferHandle.Null;
}
BufferCount++;
ulong handle64 = (uint)_buffers.Add(holder);
return Unsafe.As<ulong, BufferHandle>(ref handle64);

View File

@@ -24,6 +24,11 @@
public void Add(int cbIndex, int offset, int size)
{
if (size == 0)
{
return;
}
// Some usages can be out of bounds (vertex buffer on amd), so bound if necessary.
if (offset + size > _size)
{
@@ -39,6 +44,11 @@
public bool OverlapsWith(int cbIndex, int offset, int size)
{
if (size == 0)
{
return false;
}
int cbBase = cbIndex * _bitsPerCb;
int start = cbBase + offset / _granularity;
int end = cbBase + (offset + size - 1) / _granularity;

View File

@@ -16,6 +16,8 @@ namespace Ryujinx.Graphics.Vulkan
private Auto<DisposableBufferView> _bufferView;
private Dictionary<GAL.Format, Auto<DisposableBufferView>> _selfManagedViews;
private int _bufferCount;
public int Width { get; }
public int Height { get; }
@@ -107,7 +109,8 @@ namespace Ryujinx.Graphics.Vulkan
{
if (_bufferHandle == buffer.Handle &&
_offset == buffer.Offset &&
_size == buffer.Size)
_size == buffer.Size &&
_bufferCount == _gd.BufferManager.BufferCount)
{
return;
}
@@ -115,6 +118,7 @@ namespace Ryujinx.Graphics.Vulkan
_bufferHandle = buffer.Handle;
_offset = buffer.Offset;
_size = buffer.Size;
_bufferCount = _gd.BufferManager.BufferCount;
ReleaseImpl();
}

View File

@@ -38,18 +38,17 @@ namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator
// Read() -> (u32, buffer<nn::bcat::DeliveryCacheDirectoryEntry, 6>)
public ResultCode Read(ServiceCtx context)
{
ulong position = context.Request.ReceiveBuff[0].Position;
ulong size = context.Request.ReceiveBuff[0].Size;
ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
ulong bufferLen = context.Request.ReceiveBuff[0].Size;
byte[] data = new byte[size];
using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
{
Result result = _base.Get.Read(out int entriesRead, MemoryMarshal.Cast<byte, DeliveryCacheDirectoryEntry>(region.Memory.Span));
Result result = _base.Get.Read(out int entriesRead, MemoryMarshal.Cast<byte, DeliveryCacheDirectoryEntry>(data));
context.ResponseData.Write(entriesRead);
context.Memory.Write(position, data);
context.ResponseData.Write(entriesRead);
return (ResultCode)result.Value;
return (ResultCode)result.Value;
}
}
[CommandHipc(2)]

View File

@@ -38,20 +38,19 @@ namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator
// Read(u64) -> (u64, buffer<bytes, 6>)
public ResultCode Read(ServiceCtx context)
{
ulong position = context.Request.ReceiveBuff[0].Position;
ulong size = context.Request.ReceiveBuff[0].Size;
ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
ulong bufferLen = context.Request.ReceiveBuff[0].Size;
long offset = context.RequestData.ReadInt64();
byte[] data = new byte[size];
using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
{
Result result = _base.Get.Read(out long bytesRead, offset, region.Memory.Span);
Result result = _base.Get.Read(out long bytesRead, offset, data);
context.ResponseData.Write(bytesRead);
context.Memory.Write(position, data);
context.ResponseData.Write(bytesRead);
return (ResultCode)result.Value;
return (ResultCode)result.Value;
}
}
[CommandHipc(2)]

View File

@@ -50,18 +50,17 @@ namespace Ryujinx.HLE.HOS.Services.Bcat.ServiceCreator
// EnumerateDeliveryCacheDirectory() -> (u32, buffer<nn::bcat::DirectoryName, 6>)
public ResultCode EnumerateDeliveryCacheDirectory(ServiceCtx context)
{
ulong position = context.Request.ReceiveBuff[0].Position;
ulong size = context.Request.ReceiveBuff[0].Size;
ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
ulong bufferLen = context.Request.ReceiveBuff[0].Size;
byte[] data = new byte[size];
using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
{
Result result = _base.Get.EnumerateDeliveryCacheDirectory(out int count, MemoryMarshal.Cast<byte, DirectoryName>(region.Memory.Span));
Result result = _base.Get.EnumerateDeliveryCacheDirectory(out int count, MemoryMarshal.Cast<byte, DirectoryName>(data));
context.ResponseData.Write(count);
context.Memory.Write(position, data);
context.ResponseData.Write(count);
return (ResultCode)result.Value;
return (ResultCode)result.Value;
}
}
protected override void Dispose(bool isDisposing)

View File

@@ -17,17 +17,17 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
// Read() -> (u64 count, buffer<nn::fssrv::sf::IDirectoryEntry, 6, 0> entries)
public ResultCode Read(ServiceCtx context)
{
ulong bufferPosition = context.Request.ReceiveBuff[0].Position;
ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
ulong bufferLen = context.Request.ReceiveBuff[0].Size;
byte[] entryBuffer = new byte[bufferLen];
using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
{
Result result = _baseDirectory.Get.Read(out long entriesRead, new OutBuffer(region.Memory.Span));
Result result = _baseDirectory.Get.Read(out long entriesRead, new OutBuffer(entryBuffer));
context.ResponseData.Write(entriesRead);
context.Memory.Write(bufferPosition, entryBuffer);
context.ResponseData.Write(entriesRead);
return (ResultCode)result.Value;
return (ResultCode)result.Value;
}
}
[CommandHipc(1)]

View File

@@ -19,7 +19,8 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
// Read(u32 readOption, u64 offset, u64 size) -> (u64 out_size, buffer<u8, 0x46, 0> out_buf)
public ResultCode Read(ServiceCtx context)
{
ulong position = context.Request.ReceiveBuff[0].Position;
ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
ulong bufferLen = context.Request.ReceiveBuff[0].Size;
ReadOption readOption = context.RequestData.ReadStruct<ReadOption>();
context.RequestData.BaseStream.Position += 4;
@@ -27,15 +28,14 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
long offset = context.RequestData.ReadInt64();
long size = context.RequestData.ReadInt64();
byte[] data = new byte[context.Request.ReceiveBuff[0].Size];
using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
{
Result result = _baseFile.Get.Read(out long bytesRead, offset, new OutBuffer(region.Memory.Span), size, readOption);
Result result = _baseFile.Get.Read(out long bytesRead, offset, new OutBuffer(data), size, readOption);
context.ResponseData.Write(bytesRead);
context.Memory.Write(position, data);
context.ResponseData.Write(bytesRead);
return (ResultCode)result.Value;
return (ResultCode)result.Value;
}
}
[CommandHipc(1)]

View File

@@ -197,13 +197,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
context.ResponseData.Write(timestamp.Created);
context.ResponseData.Write(timestamp.Modified);
context.ResponseData.Write(timestamp.Accessed);
byte[] data = new byte[8];
// is valid?
data[0] = 1;
context.ResponseData.Write(data);
context.ResponseData.Write(1L); // Is valid?
return (ResultCode)result.Value;
}

View File

@@ -23,21 +23,21 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
if (context.Request.ReceiveBuff.Count > 0)
{
IpcBuffDesc buffDesc = context.Request.ReceiveBuff[0];
ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
ulong bufferLen = context.Request.ReceiveBuff[0].Size;
// Use smaller length to avoid overflows.
if (size > buffDesc.Size)
if (size > bufferLen)
{
size = buffDesc.Size;
size = bufferLen;
}
byte[] data = new byte[size];
using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
{
Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(region.Memory.Span), (long)size);
Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(data), (long)size);
context.Memory.Write(buffDesc.Position, data);
return (ResultCode)result.Value;
return (ResultCode)result.Value;
}
}
return ResultCode.Success;

View File

@@ -500,16 +500,16 @@ namespace Ryujinx.HLE.HOS.Services.Fs
SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64();
SaveDataFilter filter = context.RequestData.ReadStruct<SaveDataFilter>();
ulong bufferPosition = context.Request.ReceiveBuff[0].Position;
ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
ulong bufferLen = context.Request.ReceiveBuff[0].Size;
byte[] infoBuffer = new byte[bufferLen];
using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
{
Result result = _baseFileSystemProxy.Get.FindSaveDataWithFilter(out long count, new OutBuffer(region.Memory.Span), spaceId, in filter);
if (result.IsFailure()) return (ResultCode)result.Value;
Result result = _baseFileSystemProxy.Get.FindSaveDataWithFilter(out long count, new OutBuffer(infoBuffer), spaceId, in filter);
if (result.IsFailure()) return (ResultCode)result.Value;
context.Memory.Write(bufferPosition, infoBuffer);
context.ResponseData.Write(count);
context.ResponseData.Write(count);
}
return ResultCode.Success;
}

View File

@@ -17,17 +17,17 @@ namespace Ryujinx.HLE.HOS.Services.Fs
// ReadSaveDataInfo() -> (u64, buffer<unknown, 6>)
public ResultCode ReadSaveDataInfo(ServiceCtx context)
{
ulong bufferPosition = context.Request.ReceiveBuff[0].Position;
ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
ulong bufferLen = context.Request.ReceiveBuff[0].Size;
byte[] infoBuffer = new byte[bufferLen];
using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
{
Result result = _baseReader.Get.Read(out long readCount, new OutBuffer(region.Memory.Span));
Result result = _baseReader.Get.Read(out long readCount, new OutBuffer(infoBuffer));
context.ResponseData.Write(readCount);
context.Memory.Write(bufferPosition, infoBuffer);
context.ResponseData.Write(readCount);
return (ResultCode)result.Value;
return (ResultCode)result.Value;
}
}
protected override void Dispose(bool isDisposing)

View File

@@ -3,7 +3,6 @@ using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Memory;
using System;
using System.Collections.Concurrent;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
{
@@ -11,13 +10,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
{
private const int FlagNotFreedYet = 1;
private static ConcurrentDictionary<ulong, IdDictionary> _maps = new ConcurrentDictionary<ulong, IdDictionary>();
private static NvMapIdDictionary _maps = new NvMapIdDictionary();
public NvMapDeviceFile(ServiceCtx context, IVirtualMemoryManager memory, ulong owner) : base(context, owner)
{
IdDictionary dict = _maps.GetOrAdd(Owner, (key) => new IdDictionary());
dict.Add(0, new NvMapHandle());
}
public override NvInternalResult Ioctl(NvIoctl command, Span<byte> arguments)
@@ -232,19 +228,12 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
private int CreateHandleFromMap(NvMapHandle map)
{
IdDictionary dict = _maps.GetOrAdd(Owner, (key) => new IdDictionary());
return dict.Add(map);
return _maps.Add(map);
}
private static bool DeleteMapWithHandle(ulong pid, int handle)
{
if (_maps.TryGetValue(pid, out IdDictionary dict))
{
return dict.Delete(handle) != null;
}
return false;
return _maps.Delete(handle) != null;
}
public static void IncrementMapRefCount(ulong pid, int handle)
@@ -277,12 +266,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
public static NvMapHandle GetMapFromHandle(ulong pid, int handle)
{
if (_maps.TryGetValue(pid, out IdDictionary dict))
{
return dict.GetData<NvMapHandle>(handle);
}
return null;
return _maps.Get(handle);
}
}
}

View File

@@ -0,0 +1,61 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
{
class NvMapIdDictionary
{
private readonly ConcurrentDictionary<int, NvMapHandle> _nvmapHandles;
private int _id;
public ICollection<NvMapHandle> Values => _nvmapHandles.Values;
public NvMapIdDictionary()
{
_nvmapHandles = new ConcurrentDictionary<int, NvMapHandle>();
}
public int Add(NvMapHandle handle)
{
int id = Interlocked.Add(ref _id, 4);
if (id != 0 && _nvmapHandles.TryAdd(id, handle))
{
return id;
}
throw new InvalidOperationException("NvMap ID overflow.");
}
public NvMapHandle Get(int id)
{
if (_nvmapHandles.TryGetValue(id, out NvMapHandle handle))
{
return handle;
}
return null;
}
public NvMapHandle Delete(int id)
{
if (_nvmapHandles.TryRemove(id, out NvMapHandle handle))
{
return handle;
}
return null;
}
public ICollection<NvMapHandle> Clear()
{
ICollection<NvMapHandle> values = _nvmapHandles.Values;
_nvmapHandles.Clear();
return values;
}
}
}

View File

@@ -142,14 +142,13 @@ namespace Ryujinx.HLE.HOS.Services.Ssl.SslService
// GetHostName(buffer<bytes, 6>) -> u32
public ResultCode GetHostName(ServiceCtx context)
{
ulong hostNameDataPosition = context.Request.ReceiveBuff[0].Position;
ulong hostNameDataSize = context.Request.ReceiveBuff[0].Size;
ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
ulong bufferLen = context.Request.ReceiveBuff[0].Size;
byte[] hostNameData = new byte[hostNameDataSize];
Encoding.ASCII.GetBytes(_hostName, hostNameData);
context.Memory.Write(hostNameDataPosition, hostNameData);
using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
{
Encoding.ASCII.GetBytes(_hostName, region.Memory.Span);
}
context.ResponseData.Write((uint)_hostName.Length);