Compare commits

..

5 Commits

Author SHA1 Message Date
riperiperi
086564c3c8 HLE: Fix Mii crc generation and minor issues (#5766)
* HLE: Fix Mii crc generation

Validating CRCs for data and device involves calculating the crc of all data including the crc being checked, which should then be 0.

The crc should be _generated_ on all data _before_ the crc in the struct. It shouldn't include the crcs themselves.

This fixes all generated miis (eg. default) having invalid crcs. This does not affect mii maker, as that generates its own charinfo.

Does not fix MK8D crash.

* Fix other mii issues

* Fully define all fields for Nickname and Ver3StoreData

Fixes an issue where the nickname for a mii would only have the first character on some method calls.

* Add Array96 type
2023-10-06 19:23:39 -03:00
gdkchan
b6ac45d36d Fix SPIR-V call out arguments regression (#5767)
* Fix SPIR-V call out arguments regression

* Shader cache version bump
2023-10-06 00:18:30 -03:00
dependabot[bot]
7afae8c699 nuget: bump Microsoft.CodeAnalysis.CSharp from 4.6.0 to 4.7.0 (#5608)
Bumps [Microsoft.CodeAnalysis.CSharp](https://github.com/dotnet/roslyn) from 4.6.0 to 4.7.0.
- [Release notes](https://github.com/dotnet/roslyn/releases)
- [Changelog](https://github.com/dotnet/roslyn/blob/main/docs/Breaking%20API%20Changes.md)
- [Commits](https://github.com/dotnet/roslyn/commits)

---
updated-dependencies:
- dependency-name: Microsoft.CodeAnalysis.CSharp
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-05 13:40:03 +02:00
Marco Carvalho
7835968214 Strings should not be concatenated using '+' in a loop (#5664)
* Strings should not be concatenated using '+' in a loop

* fix IDE0090

* undo GenerateLoadOrStore

* prefer string interpolation

* Update src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs

Co-authored-by: Mary <thog@protonmail.com>

---------

Co-authored-by: Mary <thog@protonmail.com>
2023-10-05 12:41:00 +02:00
gdkchan
0aceb534cb Fix SPIR-V function calls (#5764)
* Fix SPIR-V function calls

* Shader cache version bump
2023-10-04 21:35:26 -03:00
22 changed files with 122 additions and 81 deletions

View File

@@ -20,7 +20,7 @@
<PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.3.0-beta.4" />
<PackageVersion Include="LibHac" Version="0.18.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.6.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />

View File

@@ -1,6 +1,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace ARMeilleure.Diagnostics
{
@@ -48,14 +49,15 @@ namespace ARMeilleure.Diagnostics
ulong diff = address - symbol.Start;
ulong rem = diff % symbol.ElementSize;
result = symbol.Name + "_" + diff / symbol.ElementSize;
StringBuilder resultBuilder = new();
resultBuilder.Append($"{symbol.Name}_{diff / symbol.ElementSize}");
if (rem != 0)
{
result += "+" + rem;
resultBuilder.Append($"+{rem}");
}
_symbols.TryAdd(address, result);
_symbols.TryAdd(address, resultBuilder.ToString());
return result;
}

View File

@@ -327,7 +327,7 @@ namespace Ryujinx.Ava.UI.ViewModels
string imageUrl = _amiiboList.Find(amiibo => amiibo.Equals(selected)).Image;
string usageString = "";
StringBuilder usageStringBuilder = new();
for (int i = 0; i < _amiiboList.Count; i++)
{
@@ -341,20 +341,19 @@ namespace Ryujinx.Ava.UI.ViewModels
{
foreach (AmiiboApiUsage usageItem in item.AmiiboUsage)
{
usageString += Environment.NewLine +
$"- {usageItem.Usage.Replace("/", Environment.NewLine + "-")}";
usageStringBuilder.Append($"{Environment.NewLine}- {usageItem.Usage.Replace("/", Environment.NewLine + "-")}");
writable = usageItem.Write;
}
}
}
if (usageString.Length == 0)
if (usageStringBuilder.Length == 0)
{
usageString = LocaleManager.Instance[LocaleKeys.Unknown] + ".";
usageStringBuilder.Append($"{LocaleManager.Instance[LocaleKeys.Unknown]}.");
}
Usage = $"{LocaleManager.Instance[LocaleKeys.Usage]} {(writable ? $" ({LocaleManager.Instance[LocaleKeys.Writable]})" : "")} : {usageString}";
Usage = $"{LocaleManager.Instance[LocaleKeys.Usage]} {(writable ? $" ({LocaleManager.Instance[LocaleKeys.Writable]})" : "")} : {usageStringBuilder}";
}
}

View File

@@ -756,6 +756,18 @@ namespace Ryujinx.Common.Memory
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
public struct Array96<T> : IArray<T> where T : unmanaged
{
T _e0;
Array64<T> _other;
Array31<T> _other2;
public readonly int Length => 96;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
public struct Array127<T> : IArray<T> where T : unmanaged
{
T _e0;

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 = 5757;
private const uint CodeGenVersion = 5767;
private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data";

View File

@@ -92,14 +92,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
private static string GetIndentation(int level)
{
string indentation = string.Empty;
StringBuilder indentationBuilder = new();
for (int index = 0; index < level; index++)
{
indentation += Tab;
indentationBuilder.Append(Tab);
}
return indentation;
return indentationBuilder.ToString();
}
}
}

View File

@@ -2,6 +2,7 @@ using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using Ryujinx.Graphics.Shader.StructuredIr;
using Ryujinx.Graphics.Shader.Translation;
using System;
using System.Text;
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenBallot;
using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenCall;
@@ -67,11 +68,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
int arity = (int)(info.Type & InstType.ArityMask);
string args = string.Empty;
StringBuilder builder = new();
if (atomic && (operation.StorageKind == StorageKind.StorageBuffer || operation.StorageKind == StorageKind.SharedMemory))
{
args = GenerateLoadOrStore(context, operation, isStore: false);
builder.Append(GenerateLoadOrStore(context, operation, isStore: false));
AggregateType dstType = operation.Inst == Instruction.AtomicMaxS32 || operation.Inst == Instruction.AtomicMinS32
? AggregateType.S32
@@ -79,7 +80,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
for (int argIndex = operation.SourcesCount - arity + 2; argIndex < operation.SourcesCount; argIndex++)
{
args += ", " + GetSoureExpr(context, operation.GetSource(argIndex), dstType);
builder.Append($", {GetSoureExpr(context, operation.GetSource(argIndex), dstType)}");
}
}
else
@@ -88,16 +89,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
{
if (argIndex != 0)
{
args += ", ";
builder.Append(", ");
}
AggregateType dstType = GetSrcVarType(inst, argIndex);
args += GetSoureExpr(context, operation.GetSource(argIndex), dstType);
builder.Append(GetSoureExpr(context, operation.GetSource(argIndex), dstType));
}
}
return info.OpName + '(' + args + ')';
return $"{info.OpName}({builder})";
}
else if ((info.Type & InstType.Op) != 0)
{

View File

@@ -779,17 +779,18 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
private static string GetMaskMultiDest(int mask)
{
string swizzle = ".";
StringBuilder swizzleBuilder = new();
swizzleBuilder.Append('.');
for (int i = 0; i < 4; i++)
{
if ((mask & (1 << i)) != 0)
{
swizzle += "xyzw"[i];
swizzleBuilder.Append("xyzw"[i]);
}
}
return swizzle;
return swizzleBuilder.ToString();
}
}
}

View File

@@ -316,16 +316,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
var operand = operation.GetSource(i + 1);
if (i >= function.InArguments.Length)
{
args[i] = context.GetLocalPointer((AstOperand)operand);
}
else
{
var type = function.GetArgumentType(i);
args[i] = context.Get(type, operand);
}
AstOperand local = (AstOperand)operand;
Debug.Assert(local.Type == OperandType.LocalVariable);
args[i] = context.GetLocalPointer(local);
}
var retType = function.ReturnType;

View File

@@ -2,6 +2,7 @@ using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using Ryujinx.Graphics.Shader.Translation;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;
namespace Ryujinx.Graphics.Shader.StructuredIr
@@ -62,7 +63,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
}
else
{
AddOperation(context, operation, targetLanguage);
AddOperation(context, operation, targetLanguage, functions);
}
}
}
@@ -77,7 +78,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
return context.Info;
}
private static void AddOperation(StructuredProgramContext context, Operation operation, TargetLanguage targetLanguage)
private static void AddOperation(StructuredProgramContext context, Operation operation, TargetLanguage targetLanguage, IReadOnlyList<Function> functions)
{
Instruction inst = operation.Inst;
StorageKind storageKind = operation.StorageKind;
@@ -124,14 +125,29 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
// (or at least that's what the Khronos compiler does).
// First one is the function index.
sources[0] = context.GetOperandOrCbLoad(operation.GetSource(0));
Operand funcIndexOperand = operation.GetSource(0);
Debug.Assert(funcIndexOperand.Type == OperandType.Constant);
int funcIndex = funcIndexOperand.Value;
sources[0] = new AstOperand(OperandType.Constant, funcIndex);
int inArgsCount = functions[funcIndex].InArgumentsCount;
// Remaining ones are parameters, copy them to a temp local variable.
for (int index = 1; index < operation.SourcesCount; index++)
{
AstOperand argTemp = context.NewTemp(FuncParameterType);
context.AddNode(new AstAssignment(argTemp, context.GetOperandOrCbLoad(operation.GetSource(index))));
sources[index] = argTemp;
IAstNode source = context.GetOperandOrCbLoad(operation.GetSource(index));
if (index - 1 < inArgsCount)
{
AstOperand argTemp = context.NewTemp(FuncParameterType);
context.AddNode(new AstAssignment(argTemp, source));
sources[index] = argTemp;
}
else
{
sources[index] = source;
}
}
}
else

View File

@@ -2,6 +2,7 @@ using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
namespace Ryujinx.Graphics.Shader.Translation.Optimizations
@@ -785,30 +786,31 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
private static string GetFunctionName(Operation baseOp, bool isMultiTarget, IReadOnlyList<uint> targetCbs)
{
string name = baseOp.Inst.ToString();
StringBuilder nameBuilder = new();
nameBuilder.Append(baseOp.Inst.ToString());
name += baseOp.StorageKind switch
nameBuilder.Append(baseOp.StorageKind switch
{
StorageKind.GlobalMemoryS8 => "S8",
StorageKind.GlobalMemoryS16 => "S16",
StorageKind.GlobalMemoryU8 => "U8",
StorageKind.GlobalMemoryU16 => "U16",
_ => string.Empty,
};
});
if (isMultiTarget)
{
name += "Multi";
nameBuilder.Append("Multi");
}
foreach (uint targetCb in targetCbs)
{
(int sbCbSlot, int sbCbOffset) = UnpackCbSlotAndOffset(targetCb);
name += $"_c{sbCbSlot}o{sbCbOffset}";
nameBuilder.Append($"_c{sbCbSlot}o{sbCbOffset}");
}
return name;
return nameBuilder.ToString();
}
private static bool TryGenerateStorageOp(

View File

@@ -19,6 +19,7 @@ using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using Path = System.IO.Path;
namespace Ryujinx.HLE.FileSystem
@@ -817,13 +818,13 @@ namespace Ryujinx.HLE.FileSystem
if (updateNcas.Count > 0)
{
string extraNcas = string.Empty;
StringBuilder extraNcas = new();
foreach (var entry in updateNcas)
{
foreach (var (type, path) in entry.Value)
{
extraNcas += path + Environment.NewLine;
extraNcas.AppendLine(path);
}
}
@@ -954,13 +955,13 @@ namespace Ryujinx.HLE.FileSystem
if (updateNcas.Count > 0)
{
string extraNcas = string.Empty;
StringBuilder extraNcas = new();
foreach (var entry in updateNcas)
{
foreach (var (type, path) in entry.Value)
{
extraNcas += path + Environment.NewLine;
extraNcas.AppendLine(path);
}
}

View File

@@ -436,14 +436,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
uint nameIndex = sym.NameOffset;
string name = string.Empty;
StringBuilder nameBuilder = new();
for (int chr; (chr = memory.Read<byte>(strTblAddr + nameIndex++)) != 0;)
{
name += (char)chr;
nameBuilder.Append((char)chr);
}
return new ElfSymbol(name, sym.Info, sym.Other, sym.SectionIndex, sym.ValueAddress, sym.Size);
return new ElfSymbol(nameBuilder.ToString(), sym.Info, sym.Other, sym.SectionIndex, sym.ValueAddress, sym.Size);
}
private static ElfSymbol GetSymbol32(IVirtualMemoryManager memory, ulong address, ulong strTblAddr)
@@ -452,14 +452,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
uint nameIndex = sym.NameOffset;
string name = string.Empty;
StringBuilder nameBuilder = new();
for (int chr; (chr = memory.Read<byte>(strTblAddr + nameIndex++)) != 0;)
{
name += (char)chr;
nameBuilder.Append((char)chr);
}
return new ElfSymbol(name, sym.Info, sym.Other, sym.SectionIndex, sym.ValueAddress, sym.Size);
return new ElfSymbol(nameBuilder.ToString(), sym.Info, sym.Other, sym.SectionIndex, sym.ValueAddress, sym.Size);
}
}
}

View File

@@ -290,7 +290,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii
{
coreData = new CoreData();
if (charInfo.IsValid())
if (!charInfo.IsValid())
{
return ResultCode.InvalidCharInfo;
}

View File

@@ -1,4 +1,5 @@
using System;
using Ryujinx.Common.Memory;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using static Ryujinx.HLE.HOS.Services.Mii.Types.RandomMiiConstants;
@@ -10,9 +11,9 @@ namespace Ryujinx.HLE.HOS.Services.Mii.Types
{
public const int Size = 0x30;
private byte _storage;
private Array48<byte> _storage;
public Span<byte> Storage => MemoryMarshal.CreateSpan(ref _storage, Size);
public Span<byte> Storage => _storage.AsSpan();
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 0x18)]
public struct ElementInfo

View File

@@ -1,4 +1,5 @@
using System;
using Ryujinx.Common.Memory;
using System;
using System.Runtime.InteropServices;
using System.Text;
@@ -10,12 +11,12 @@ namespace Ryujinx.HLE.HOS.Services.Mii.Types
public const int CharCount = 10;
private const int SizeConst = (CharCount + 1) * 2;
private byte _storage;
private Array22<byte> _storage;
public static Nickname Default => FromString("no name");
public static Nickname Question => FromString("???");
public Span<byte> Raw => MemoryMarshal.CreateSpan(ref _storage, SizeConst);
public Span<byte> Raw => _storage.AsSpan();
private ReadOnlySpan<ushort> Characters => MemoryMarshal.Cast<byte, ushort>(Raw);

View File

@@ -62,7 +62,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii.Types
private ushort CalculateDataCrc()
{
return Helper.CalculateCrc16(AsSpanWithoutDeviceCrc(), 0, true);
return Helper.CalculateCrc16(AsSpanWithoutCrcs(), 0, true);
}
private ushort CalculateDeviceCrc()
@@ -71,7 +71,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii.Types
ushort deviceIdCrc16 = Helper.CalculateCrc16(SpanHelpers.AsByteSpan(ref deviceId), 0, false);
return Helper.CalculateCrc16(AsSpan(), deviceIdCrc16, true);
return Helper.CalculateCrc16(AsSpanWithoutDeviceCrc(), deviceIdCrc16, true);
}
private ReadOnlySpan<byte> AsSpan()
@@ -84,6 +84,11 @@ namespace Ryujinx.HLE.HOS.Services.Mii.Types
return AsSpan()[..(Size - 2)];
}
private ReadOnlySpan<byte> AsSpanWithoutCrcs()
{
return AsSpan()[..(Size - 4)];
}
public static StoreData BuildDefault(UtilityImpl utilImpl, uint index)
{
StoreData result = new()

View File

@@ -1,4 +1,6 @@
using System;
using Ryujinx.Common.Memory;
using Ryujinx.Common.Utilities;
using System;
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Mii.Types
@@ -8,9 +10,9 @@ namespace Ryujinx.HLE.HOS.Services.Mii.Types
{
public const int Size = 0x60;
private byte _storage;
private Array96<byte> _storage;
public Span<byte> Storage => MemoryMarshal.CreateSpan(ref _storage, Size);
public Span<byte> Storage => _storage.AsSpan();
// TODO: define all getters/setters
}

View File

@@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Ryujinx.HLE.HOS.Services.Sm
{
@@ -235,7 +236,7 @@ namespace Ryujinx.HLE.HOS.Services.Sm
private static string ReadName(ServiceCtx context)
{
string name = string.Empty;
StringBuilder nameBuilder = new();
for (int index = 0; index < 8 &&
context.RequestData.BaseStream.Position <
@@ -245,11 +246,11 @@ namespace Ryujinx.HLE.HOS.Services.Sm
if (chr >= 0x20 && chr < 0x7f)
{
name += (char)chr;
nameBuilder.Append((char)chr);
}
}
return name;
return nameBuilder.ToString();
}
public override void DestroyAtExit()

View File

@@ -142,7 +142,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
// OpenDisplay(nn::vi::DisplayName) -> u64 display_id
public ResultCode OpenDisplay(ServiceCtx context)
{
string name = "";
StringBuilder nameBuilder = new();
for (int index = 0; index < 8 && context.RequestData.BaseStream.Position < context.RequestData.BaseStream.Length; index++)
{
@@ -150,11 +150,11 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
if (chr >= 0x20 && chr < 0x7f)
{
name += (char)chr;
nameBuilder.Append((char)chr);
}
}
return OpenDisplayImpl(context, name);
return OpenDisplayImpl(context, nameBuilder.ToString());
}
[CommandCmif(1011)]

View File

@@ -1,5 +1,6 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace Ryujinx.Horizon.Sdk.Sm
{
@@ -78,7 +79,7 @@ namespace Ryujinx.Horizon.Sdk.Sm
public override string ToString()
{
string name = string.Empty;
StringBuilder nameBuilder = new();
for (int index = 0; index < sizeof(ulong); index++)
{
@@ -89,10 +90,10 @@ namespace Ryujinx.Horizon.Sdk.Sm
break;
}
name += (char)character;
nameBuilder.Append((char)character);
}
return name;
return nameBuilder.ToString();
}
}
}

View File

@@ -1,5 +1,6 @@
using Microsoft.CodeAnalysis;
using System.Linq;
using System.Text;
namespace Ryujinx.Ui.LocaleGenerator
{
@@ -15,15 +16,17 @@ namespace Ryujinx.Ui.LocaleGenerator
context.RegisterSourceOutput(contents, (spc, content) =>
{
var lines = content.Split('\n').Where(x => x.Trim().StartsWith("\"")).Select(x => x.Split(':')[0].Trim().Replace("\"", ""));
string enumSource = "namespace Ryujinx.Ava.Common.Locale;\n";
enumSource += "internal enum LocaleKeys\n{\n";
StringBuilder enumSourceBuilder = new();
enumSourceBuilder.AppendLine("namespace Ryujinx.Ava.Common.Locale;");
enumSourceBuilder.AppendLine("internal enum LocaleKeys");
enumSourceBuilder.AppendLine("{");
foreach (var line in lines)
{
enumSource += $" {line},\n";
enumSourceBuilder.AppendLine($" {line},");
}
enumSource += "}\n";
enumSourceBuilder.AppendLine("}");
spc.AddSource("LocaleKeys", enumSource);
spc.AddSource("LocaleKeys", enumSourceBuilder.ToString());
});
}
}