aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs
diff options
context:
space:
mode:
authorAlex Barney <thealexbarney@gmail.com>2019-12-26 23:09:49 -0700
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commitd1ab9fb42c2fd9f018d4410ca619cd66294eafc9 (patch)
treedcac71560b921f29d73ee6e21f235528184d9f84 /Ryujinx.Graphics.Texture/Astc/AstcPixel.cs
parent947e14d3be0f7c5e4b6f77df204ec675b8e9e719 (diff)
ASTC optimizations (#845)
* ASTC optimizations * Move code to Ryujinx.Common * Support 3D textures * Address feedback * Remove ASTC logging * Use stackalloc instead of a Buffer20 struct * Code style and cleanup * Respond to feedback * Rearrange public/private property ordering
Diffstat (limited to 'Ryujinx.Graphics.Texture/Astc/AstcPixel.cs')
-rw-r--r--Ryujinx.Graphics.Texture/Astc/AstcPixel.cs112
1 files changed, 21 insertions, 91 deletions
diff --git a/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs b/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs
index 7d127878..13197714 100644
--- a/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs
+++ b/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs
@@ -1,16 +1,23 @@
using System;
-using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Texture.Astc
{
- class AstcPixel
+ [StructLayout(LayoutKind.Sequential)]
+ struct AstcPixel
{
- public short R { get; set; }
- public short G { get; set; }
- public short B { get; set; }
- public short A { get; set; }
+ internal const int StructSize = 12;
- byte[] _bitDepth = new byte[4];
+ 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)
{
@@ -19,8 +26,7 @@ namespace Ryujinx.Graphics.Texture.Astc
G = g;
B = b;
- for (int i = 0; i < 4; i++)
- _bitDepth[i] = 8;
+ _bitDepthInt = 0x08080808;
}
public void ClampByte()
@@ -33,96 +39,20 @@ namespace Ryujinx.Graphics.Texture.Astc
public short GetComponent(int index)
{
- switch(index)
- {
- case 0: return A;
- case 1: return R;
- case 2: return G;
- case 3: return B;
- }
-
- return 0;
+ return Components[index];
}
public void SetComponent(int index, int value)
{
- switch (index)
- {
- case 0:
- A = (short)value;
- break;
- case 1:
- R = (short)value;
- break;
- case 2:
- G = (short)value;
- break;
- case 3:
- B = (short)value;
- break;
- }
- }
-
- public void ChangeBitDepth(byte[] depth)
- {
- for (int i = 0; i< 4; i++)
- {
- int value = ChangeBitDepth(GetComponent(i), _bitDepth[i], depth[i]);
-
- SetComponent(i, value);
- _bitDepth[i] = depth[i];
- }
- }
-
- short ChangeBitDepth(short value, byte oldDepth, byte newDepth)
- {
- Debug.Assert(newDepth <= 8);
- Debug.Assert(oldDepth <= 8);
-
- if (oldDepth == newDepth)
- {
- // Do nothing
- return value;
- }
- else if (oldDepth == 0 && newDepth != 0)
- {
- return (short)((1 << newDepth) - 1);
- }
- else if (newDepth > oldDepth)
- {
- return (short)BitArrayStream.Replicate(value, oldDepth, newDepth);
- }
- else
- {
- // oldDepth > newDepth
- if (newDepth == 0)
- {
- return 0xFF;
- }
- else
- {
- byte bitsWasted = (byte)(oldDepth - newDepth);
- short tempValue = value;
-
- tempValue = (short)((tempValue + (1 << (bitsWasted - 1))) >> bitsWasted);
- tempValue = Math.Min(Math.Max((short)0, tempValue), (short)((1 << newDepth) - 1));
-
- return (byte)(tempValue);
- }
- }
+ Components[index] = (short)value;
}
public int Pack()
{
- AstcPixel newPixel = new AstcPixel(A, R, G, B);
- byte[] eightBitDepth = { 8, 8, 8, 8 };
-
- newPixel.ChangeBitDepth(eightBitDepth);
-
- return (byte)newPixel.A << 24 |
- (byte)newPixel.B << 16 |
- (byte)newPixel.G << 8 |
- (byte)newPixel.R << 0;
+ return A << 24 |
+ B << 16 |
+ G << 8 |
+ R << 0;
}
// Adds more precision to the blue channel as described