aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs')
-rw-r--r--src/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs68
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));
+ }
+ }
+}