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
This commit is contained in:
parent
947e14d3be
commit
d1ab9fb42c
12 changed files with 1009 additions and 599 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue