mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-04-21 18:13:14 +02:00

* Add workflow to perform automated checks for PRs * Downgrade Microsoft.CodeAnalysis to 4.4.0 This is a workaround to fix issues with dotnet-format. See: - https://github.com/dotnet/format/issues/1805 - https://github.com/dotnet/format/issues/1800 * Adjust editorconfig to be more compatible with Ryujinx code-style * Adjust .editorconfig line endings to match .gitattributes * Disable 'prefer switch expression' rule * Remove naming styles These are the default rules, so we don't need to override them. * Silence IDE0060 in .editorconfig * Slightly adjust .editorconfig * Add lost workflow changes * Move .editorconfig comment to the top * .editorconfig: private static readonly fields should be _lowerCamelCase * .editorconfig: Remove alignment for declarations as well * editorconfig: Add rule for local constants * Disable CA1822 for HLE services * Disable CA1822 for ViewModels Bindings won't work with static members, but this issue is silently ignored. * Run dotnet format for the whole solution * Check result code of SDL_GetDisplayBounds * Fix dotnet format style issues * Add missing trailing commas * Update Microsoft.CodeAnalysis.CSharp to 4.6.0 Skipping 4.5.0 since it breaks dotnet format * Restore old default naming rules for dotnet format * Add naming rule exception for CPU tests * checks: Include all files before excluding paths * Fix dotnet format issues * Check dotnet format version * checks: Run dotnet format with severity info again * checks: Disable naming style rules until they won't crash the process anymore * Remove unread private member * checks: Attempt to run analyzers 3 times before giving up * checks: Enable naming style rules again with the new retry logic
345 lines
14 KiB
C#
345 lines
14 KiB
C#
using System;
|
|
using System.Numerics;
|
|
|
|
namespace Ryujinx.Graphics.Texture.Astc
|
|
{
|
|
internal struct IntegerEncoded
|
|
{
|
|
internal const int StructSize = 8;
|
|
private static readonly IntegerEncoded[] _encodings;
|
|
|
|
public enum EIntegerEncoding : byte
|
|
{
|
|
JustBits,
|
|
Quint,
|
|
Trit,
|
|
}
|
|
|
|
readonly EIntegerEncoding _encoding;
|
|
public byte NumberBits { get; private set; }
|
|
public byte TritValue { get; private set; }
|
|
public byte QuintValue { get; private set; }
|
|
public int BitValue { get; private set; }
|
|
|
|
static IntegerEncoded()
|
|
{
|
|
_encodings = new IntegerEncoded[0x100];
|
|
|
|
for (int i = 0; i < _encodings.Length; i++)
|
|
{
|
|
_encodings[i] = CreateEncodingCalc(i);
|
|
}
|
|
}
|
|
|
|
public IntegerEncoded(EIntegerEncoding encoding, int numBits)
|
|
{
|
|
_encoding = encoding;
|
|
NumberBits = (byte)numBits;
|
|
BitValue = 0;
|
|
TritValue = 0;
|
|
QuintValue = 0;
|
|
}
|
|
|
|
public readonly bool MatchesEncoding(IntegerEncoded other)
|
|
{
|
|
return _encoding == other._encoding && NumberBits == other.NumberBits;
|
|
}
|
|
|
|
public readonly EIntegerEncoding GetEncoding()
|
|
{
|
|
return _encoding;
|
|
}
|
|
|
|
public readonly int GetBitLength(int numberVals)
|
|
{
|
|
int totalBits = NumberBits * numberVals;
|
|
if (_encoding == EIntegerEncoding.Trit)
|
|
{
|
|
totalBits += (numberVals * 8 + 4) / 5;
|
|
}
|
|
else if (_encoding == EIntegerEncoding.Quint)
|
|
{
|
|
totalBits += (numberVals * 7 + 2) / 3;
|
|
}
|
|
return totalBits;
|
|
}
|
|
|
|
public static IntegerEncoded CreateEncoding(int maxVal)
|
|
{
|
|
return _encodings[maxVal];
|
|
}
|
|
|
|
private static IntegerEncoded CreateEncodingCalc(int maxVal)
|
|
{
|
|
while (maxVal > 0)
|
|
{
|
|
int check = maxVal + 1;
|
|
|
|
// Is maxVal a power of two?
|
|
if ((check & (check - 1)) == 0)
|
|
{
|
|
return new IntegerEncoded(EIntegerEncoding.JustBits, BitOperations.PopCount((uint)maxVal));
|
|
}
|
|
|
|
// Is maxVal of the type 3*2^n - 1?
|
|
if ((check % 3 == 0) && ((check / 3) & ((check / 3) - 1)) == 0)
|
|
{
|
|
return new IntegerEncoded(EIntegerEncoding.Trit, BitOperations.PopCount((uint)(check / 3 - 1)));
|
|
}
|
|
|
|
// Is maxVal of the type 5*2^n - 1?
|
|
if ((check % 5 == 0) && ((check / 5) & ((check / 5) - 1)) == 0)
|
|
{
|
|
return new IntegerEncoded(EIntegerEncoding.Quint, BitOperations.PopCount((uint)(check / 5 - 1)));
|
|
}
|
|
|
|
// Apparently it can't be represented with a bounded integer sequence...
|
|
// just iterate.
|
|
maxVal--;
|
|
}
|
|
|
|
return new IntegerEncoded(EIntegerEncoding.JustBits, 0);
|
|
}
|
|
|
|
public static void DecodeTritBlock(
|
|
ref BitStream128 bitStream,
|
|
ref IntegerSequence listIntegerEncoded,
|
|
int numberBitsPerValue)
|
|
{
|
|
// Implement the algorithm in section C.2.12
|
|
Span<int> m = stackalloc int[5];
|
|
|
|
m[0] = bitStream.ReadBits(numberBitsPerValue);
|
|
int encoded = bitStream.ReadBits(2);
|
|
m[1] = bitStream.ReadBits(numberBitsPerValue);
|
|
encoded |= bitStream.ReadBits(2) << 2;
|
|
m[2] = bitStream.ReadBits(numberBitsPerValue);
|
|
encoded |= bitStream.ReadBits(1) << 4;
|
|
m[3] = bitStream.ReadBits(numberBitsPerValue);
|
|
encoded |= bitStream.ReadBits(2) << 5;
|
|
m[4] = bitStream.ReadBits(numberBitsPerValue);
|
|
encoded |= bitStream.ReadBits(1) << 7;
|
|
|
|
ReadOnlySpan<byte> encodings = GetTritEncoding(encoded);
|
|
|
|
IntegerEncoded intEncoded = new(EIntegerEncoding.Trit, numberBitsPerValue);
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
intEncoded.BitValue = m[i];
|
|
intEncoded.TritValue = encodings[i];
|
|
|
|
listIntegerEncoded.Add(ref intEncoded);
|
|
}
|
|
}
|
|
|
|
public static void DecodeQuintBlock(
|
|
ref BitStream128 bitStream,
|
|
ref IntegerSequence listIntegerEncoded,
|
|
int numberBitsPerValue)
|
|
{
|
|
ReadOnlySpan<byte> interleavedBits = new byte[] { 3, 2, 2 };
|
|
|
|
// Implement the algorithm in section C.2.12
|
|
Span<int> m = stackalloc int[3];
|
|
ulong encoded = 0;
|
|
int encodedBitsRead = 0;
|
|
|
|
for (int i = 0; i < m.Length; i++)
|
|
{
|
|
m[i] = bitStream.ReadBits(numberBitsPerValue);
|
|
|
|
uint encodedBits = (uint)bitStream.ReadBits(interleavedBits[i]);
|
|
|
|
encoded |= encodedBits << encodedBitsRead;
|
|
encodedBitsRead += interleavedBits[i];
|
|
}
|
|
|
|
ReadOnlySpan<byte> encodings = GetQuintEncoding((int)encoded);
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
IntegerEncoded intEncoded = new(EIntegerEncoding.Quint, numberBitsPerValue)
|
|
{
|
|
BitValue = m[i],
|
|
QuintValue = encodings[i],
|
|
};
|
|
|
|
listIntegerEncoded.Add(ref intEncoded);
|
|
}
|
|
}
|
|
|
|
public static void DecodeIntegerSequence(
|
|
ref IntegerSequence decodeIntegerSequence,
|
|
ref BitStream128 bitStream,
|
|
int maxRange,
|
|
int numberValues)
|
|
{
|
|
// Determine encoding parameters
|
|
IntegerEncoded intEncoded = CreateEncoding(maxRange);
|
|
|
|
// Start decoding
|
|
int numberValuesDecoded = 0;
|
|
while (numberValuesDecoded < numberValues)
|
|
{
|
|
switch (intEncoded.GetEncoding())
|
|
{
|
|
case EIntegerEncoding.Quint:
|
|
{
|
|
DecodeQuintBlock(ref bitStream, ref decodeIntegerSequence, intEncoded.NumberBits);
|
|
numberValuesDecoded += 3;
|
|
|
|
break;
|
|
}
|
|
|
|
case EIntegerEncoding.Trit:
|
|
{
|
|
DecodeTritBlock(ref bitStream, ref decodeIntegerSequence, intEncoded.NumberBits);
|
|
numberValuesDecoded += 5;
|
|
|
|
break;
|
|
}
|
|
|
|
case EIntegerEncoding.JustBits:
|
|
{
|
|
intEncoded.BitValue = bitStream.ReadBits(intEncoded.NumberBits);
|
|
decodeIntegerSequence.Add(ref intEncoded);
|
|
numberValuesDecoded++;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static ReadOnlySpan<byte> GetTritEncoding(int index)
|
|
{
|
|
return TritEncodings.Slice(index * 5, 5);
|
|
}
|
|
|
|
private static ReadOnlySpan<byte> GetQuintEncoding(int index)
|
|
{
|
|
return QuintEncodings.Slice(index * 3, 3);
|
|
}
|
|
|
|
private static ReadOnlySpan<byte> TritEncodings => new byte[]
|
|
{
|
|
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0,
|
|
0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0,
|
|
2, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 2, 0, 0, 0,
|
|
1, 2, 0, 0, 0, 2, 2, 0, 0, 0, 2, 0, 2, 0, 0,
|
|
0, 2, 2, 0, 0, 1, 2, 2, 0, 0, 2, 2, 2, 0, 0,
|
|
2, 0, 2, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0,
|
|
2, 0, 1, 0, 0, 0, 1, 2, 0, 0, 0, 1, 1, 0, 0,
|
|
1, 1, 1, 0, 0, 2, 1, 1, 0, 0, 1, 1, 2, 0, 0,
|
|
0, 2, 1, 0, 0, 1, 2, 1, 0, 0, 2, 2, 1, 0, 0,
|
|
2, 1, 2, 0, 0, 0, 0, 0, 2, 2, 1, 0, 0, 2, 2,
|
|
2, 0, 0, 2, 2, 0, 0, 2, 2, 2, 0, 0, 0, 1, 0,
|
|
1, 0, 0, 1, 0, 2, 0, 0, 1, 0, 0, 0, 2, 1, 0,
|
|
0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 2, 1, 0, 1, 0,
|
|
1, 0, 2, 1, 0, 0, 2, 0, 1, 0, 1, 2, 0, 1, 0,
|
|
2, 2, 0, 1, 0, 2, 0, 2, 1, 0, 0, 2, 2, 1, 0,
|
|
1, 2, 2, 1, 0, 2, 2, 2, 1, 0, 2, 0, 2, 1, 0,
|
|
0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 2, 0, 1, 1, 0,
|
|
0, 1, 2, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0,
|
|
2, 1, 1, 1, 0, 1, 1, 2, 1, 0, 0, 2, 1, 1, 0,
|
|
1, 2, 1, 1, 0, 2, 2, 1, 1, 0, 2, 1, 2, 1, 0,
|
|
0, 1, 0, 2, 2, 1, 1, 0, 2, 2, 2, 1, 0, 2, 2,
|
|
1, 0, 2, 2, 2, 0, 0, 0, 2, 0, 1, 0, 0, 2, 0,
|
|
2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 1, 0, 2, 0,
|
|
1, 1, 0, 2, 0, 2, 1, 0, 2, 0, 1, 0, 2, 2, 0,
|
|
0, 2, 0, 2, 0, 1, 2, 0, 2, 0, 2, 2, 0, 2, 0,
|
|
2, 0, 2, 2, 0, 0, 2, 2, 2, 0, 1, 2, 2, 2, 0,
|
|
2, 2, 2, 2, 0, 2, 0, 2, 2, 0, 0, 0, 1, 2, 0,
|
|
1, 0, 1, 2, 0, 2, 0, 1, 2, 0, 0, 1, 2, 2, 0,
|
|
0, 1, 1, 2, 0, 1, 1, 1, 2, 0, 2, 1, 1, 2, 0,
|
|
1, 1, 2, 2, 0, 0, 2, 1, 2, 0, 1, 2, 1, 2, 0,
|
|
2, 2, 1, 2, 0, 2, 1, 2, 2, 0, 0, 2, 0, 2, 2,
|
|
1, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2,
|
|
0, 0, 0, 0, 2, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2,
|
|
0, 0, 2, 0, 2, 0, 1, 0, 0, 2, 1, 1, 0, 0, 2,
|
|
2, 1, 0, 0, 2, 1, 0, 2, 0, 2, 0, 2, 0, 0, 2,
|
|
1, 2, 0, 0, 2, 2, 2, 0, 0, 2, 2, 0, 2, 0, 2,
|
|
0, 2, 2, 0, 2, 1, 2, 2, 0, 2, 2, 2, 2, 0, 2,
|
|
2, 0, 2, 0, 2, 0, 0, 1, 0, 2, 1, 0, 1, 0, 2,
|
|
2, 0, 1, 0, 2, 0, 1, 2, 0, 2, 0, 1, 1, 0, 2,
|
|
1, 1, 1, 0, 2, 2, 1, 1, 0, 2, 1, 1, 2, 0, 2,
|
|
0, 2, 1, 0, 2, 1, 2, 1, 0, 2, 2, 2, 1, 0, 2,
|
|
2, 1, 2, 0, 2, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 1,
|
|
1, 0, 0, 0, 1, 2, 0, 0, 0, 1, 0, 0, 2, 0, 1,
|
|
0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 2, 1, 0, 0, 1,
|
|
1, 0, 2, 0, 1, 0, 2, 0, 0, 1, 1, 2, 0, 0, 1,
|
|
2, 2, 0, 0, 1, 2, 0, 2, 0, 1, 0, 2, 2, 0, 1,
|
|
1, 2, 2, 0, 1, 2, 2, 2, 0, 1, 2, 0, 2, 0, 1,
|
|
0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 2, 0, 1, 0, 1,
|
|
0, 1, 2, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1,
|
|
2, 1, 1, 0, 1, 1, 1, 2, 0, 1, 0, 2, 1, 0, 1,
|
|
1, 2, 1, 0, 1, 2, 2, 1, 0, 1, 2, 1, 2, 0, 1,
|
|
0, 0, 1, 2, 2, 1, 0, 1, 2, 2, 2, 0, 1, 2, 2,
|
|
0, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1,
|
|
2, 0, 0, 1, 1, 0, 0, 2, 1, 1, 0, 1, 0, 1, 1,
|
|
1, 1, 0, 1, 1, 2, 1, 0, 1, 1, 1, 0, 2, 1, 1,
|
|
0, 2, 0, 1, 1, 1, 2, 0, 1, 1, 2, 2, 0, 1, 1,
|
|
2, 0, 2, 1, 1, 0, 2, 2, 1, 1, 1, 2, 2, 1, 1,
|
|
2, 2, 2, 1, 1, 2, 0, 2, 1, 1, 0, 0, 1, 1, 1,
|
|
1, 0, 1, 1, 1, 2, 0, 1, 1, 1, 0, 1, 2, 1, 1,
|
|
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1,
|
|
1, 1, 2, 1, 1, 0, 2, 1, 1, 1, 1, 2, 1, 1, 1,
|
|
2, 2, 1, 1, 1, 2, 1, 2, 1, 1, 0, 1, 1, 2, 2,
|
|
1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 2,
|
|
0, 0, 0, 2, 1, 1, 0, 0, 2, 1, 2, 0, 0, 2, 1,
|
|
0, 0, 2, 2, 1, 0, 1, 0, 2, 1, 1, 1, 0, 2, 1,
|
|
2, 1, 0, 2, 1, 1, 0, 2, 2, 1, 0, 2, 0, 2, 1,
|
|
1, 2, 0, 2, 1, 2, 2, 0, 2, 1, 2, 0, 2, 2, 1,
|
|
0, 2, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1,
|
|
2, 0, 2, 2, 1, 0, 0, 1, 2, 1, 1, 0, 1, 2, 1,
|
|
2, 0, 1, 2, 1, 0, 1, 2, 2, 1, 0, 1, 1, 2, 1,
|
|
1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1,
|
|
0, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2, 1, 2, 1,
|
|
2, 1, 2, 2, 1, 0, 2, 1, 2, 2, 1, 2, 1, 2, 2,
|
|
2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 0, 0, 0, 1, 2,
|
|
1, 0, 0, 1, 2, 2, 0, 0, 1, 2, 0, 0, 2, 1, 2,
|
|
0, 1, 0, 1, 2, 1, 1, 0, 1, 2, 2, 1, 0, 1, 2,
|
|
1, 0, 2, 1, 2, 0, 2, 0, 1, 2, 1, 2, 0, 1, 2,
|
|
2, 2, 0, 1, 2, 2, 0, 2, 1, 2, 0, 2, 2, 1, 2,
|
|
1, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 0, 2, 1, 2,
|
|
0, 0, 1, 1, 2, 1, 0, 1, 1, 2, 2, 0, 1, 1, 2,
|
|
0, 1, 2, 1, 2, 0, 1, 1, 1, 2, 1, 1, 1, 1, 2,
|
|
2, 1, 1, 1, 2, 1, 1, 2, 1, 2, 0, 2, 1, 1, 2,
|
|
1, 2, 1, 1, 2, 2, 2, 1, 1, 2, 2, 1, 2, 1, 2,
|
|
0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 1, 2, 2, 2,
|
|
};
|
|
|
|
private static ReadOnlySpan<byte> QuintEncodings => new byte[]
|
|
{
|
|
0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 0,
|
|
0, 4, 0, 4, 4, 0, 4, 4, 4, 0, 1, 0, 1, 1, 0,
|
|
2, 1, 0, 3, 1, 0, 4, 1, 0, 1, 4, 0, 4, 4, 1,
|
|
4, 4, 4, 0, 2, 0, 1, 2, 0, 2, 2, 0, 3, 2, 0,
|
|
4, 2, 0, 2, 4, 0, 4, 4, 2, 4, 4, 4, 0, 3, 0,
|
|
1, 3, 0, 2, 3, 0, 3, 3, 0, 4, 3, 0, 3, 4, 0,
|
|
4, 4, 3, 4, 4, 4, 0, 0, 1, 1, 0, 1, 2, 0, 1,
|
|
3, 0, 1, 4, 0, 1, 0, 4, 1, 4, 0, 4, 0, 4, 4,
|
|
0, 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, 4, 1, 1,
|
|
1, 4, 1, 4, 1, 4, 1, 4, 4, 0, 2, 1, 1, 2, 1,
|
|
2, 2, 1, 3, 2, 1, 4, 2, 1, 2, 4, 1, 4, 2, 4,
|
|
2, 4, 4, 0, 3, 1, 1, 3, 1, 2, 3, 1, 3, 3, 1,
|
|
4, 3, 1, 3, 4, 1, 4, 3, 4, 3, 4, 4, 0, 0, 2,
|
|
1, 0, 2, 2, 0, 2, 3, 0, 2, 4, 0, 2, 0, 4, 2,
|
|
2, 0, 4, 3, 0, 4, 0, 1, 2, 1, 1, 2, 2, 1, 2,
|
|
3, 1, 2, 4, 1, 2, 1, 4, 2, 2, 1, 4, 3, 1, 4,
|
|
0, 2, 2, 1, 2, 2, 2, 2, 2, 3, 2, 2, 4, 2, 2,
|
|
2, 4, 2, 2, 2, 4, 3, 2, 4, 0, 3, 2, 1, 3, 2,
|
|
2, 3, 2, 3, 3, 2, 4, 3, 2, 3, 4, 2, 2, 3, 4,
|
|
3, 3, 4, 0, 0, 3, 1, 0, 3, 2, 0, 3, 3, 0, 3,
|
|
4, 0, 3, 0, 4, 3, 0, 0, 4, 1, 0, 4, 0, 1, 3,
|
|
1, 1, 3, 2, 1, 3, 3, 1, 3, 4, 1, 3, 1, 4, 3,
|
|
0, 1, 4, 1, 1, 4, 0, 2, 3, 1, 2, 3, 2, 2, 3,
|
|
3, 2, 3, 4, 2, 3, 2, 4, 3, 0, 2, 4, 1, 2, 4,
|
|
0, 3, 3, 1, 3, 3, 2, 3, 3, 3, 3, 3, 4, 3, 3,
|
|
3, 4, 3, 0, 3, 4, 1, 3, 4,
|
|
};
|
|
}
|
|
}
|