diff options
Diffstat (limited to 'src/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs')
| -rw-r--r-- | src/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs b/src/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs new file mode 100644 index 00000000..13197714 --- /dev/null +++ b/src/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs @@ -0,0 +1,68 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Ryujinx.Graphics.Texture.Astc +{ + [StructLayout(LayoutKind.Sequential)] + struct AstcPixel + { + internal const int StructSize = 12; + + public short A; + public short R; + public short G; + public short B; + + private uint _bitDepthInt; + + private Span<byte> BitDepth => MemoryMarshal.CreateSpan(ref Unsafe.As<uint, byte>(ref _bitDepthInt), 4); + private Span<short> Components => MemoryMarshal.CreateSpan(ref A, 4); + + public AstcPixel(short a, short r, short g, short b) + { + A = a; + R = r; + G = g; + B = b; + + _bitDepthInt = 0x08080808; + } + + public void ClampByte() + { + R = Math.Min(Math.Max(R, (short)0), (short)255); + G = Math.Min(Math.Max(G, (short)0), (short)255); + B = Math.Min(Math.Max(B, (short)0), (short)255); + A = Math.Min(Math.Max(A, (short)0), (short)255); + } + + public short GetComponent(int index) + { + return Components[index]; + } + + public void SetComponent(int index, int value) + { + Components[index] = (short)value; + } + + public int Pack() + { + return A << 24 | + B << 16 | + G << 8 | + R << 0; + } + + // Adds more precision to the blue channel as described + // in C.2.14 + public static AstcPixel BlueContract(int a, int r, int g, int b) + { + return new AstcPixel((short)(a), + (short)((r + b) >> 1), + (short)((g + b) >> 1), + (short)(b)); + } + } +} |
