Renaming part 6
This commit is contained in:
parent
1bd42db07e
commit
33cb66370b
12 changed files with 1101 additions and 1101 deletions
|
@ -190,7 +190,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
int textureBlockHeight = ImageUtils.GetBlockHeight(image.Format);
|
||||
int textureBlockDepth = ImageUtils.GetBlockDepth(image.Format);
|
||||
|
||||
data = ASTCDecoder.DecodeToRGBA8888(
|
||||
data = AstcDecoder.DecodeToRGBA8888(
|
||||
data,
|
||||
textureBlockWidth,
|
||||
textureBlockHeight,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,24 +3,24 @@ using System.Diagnostics;
|
|||
|
||||
namespace Ryujinx.Graphics.Texture
|
||||
{
|
||||
class ASTCPixel
|
||||
class AstcPixel
|
||||
{
|
||||
public short R { get; set; }
|
||||
public short G { get; set; }
|
||||
public short B { get; set; }
|
||||
public short A { get; set; }
|
||||
|
||||
byte[] BitDepth = new byte[4];
|
||||
byte[] _bitDepth = new byte[4];
|
||||
|
||||
public ASTCPixel(short _A, short _R, short _G, short _B)
|
||||
public AstcPixel(short a, short r, short g, short b)
|
||||
{
|
||||
A = _A;
|
||||
R = _R;
|
||||
G = _G;
|
||||
B = _B;
|
||||
A = a;
|
||||
R = r;
|
||||
G = g;
|
||||
B = b;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
BitDepth[i] = 8;
|
||||
_bitDepth[i] = 8;
|
||||
}
|
||||
|
||||
public void ClampByte()
|
||||
|
@ -31,9 +31,9 @@ namespace Ryujinx.Graphics.Texture
|
|||
A = Math.Min(Math.Max(A, (short)0), (short)255);
|
||||
}
|
||||
|
||||
public short GetComponent(int Index)
|
||||
public short GetComponent(int index)
|
||||
{
|
||||
switch(Index)
|
||||
switch(index)
|
||||
{
|
||||
case 0: return A;
|
||||
case 1: return R;
|
||||
|
@ -44,92 +44,92 @@ namespace Ryujinx.Graphics.Texture
|
|||
return 0;
|
||||
}
|
||||
|
||||
public void SetComponent(int Index, int Value)
|
||||
public void SetComponent(int index, int value)
|
||||
{
|
||||
switch (Index)
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
A = (short)Value;
|
||||
A = (short)value;
|
||||
break;
|
||||
case 1:
|
||||
R = (short)Value;
|
||||
R = (short)value;
|
||||
break;
|
||||
case 2:
|
||||
G = (short)Value;
|
||||
G = (short)value;
|
||||
break;
|
||||
case 3:
|
||||
B = (short)Value;
|
||||
B = (short)value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeBitDepth(byte[] Depth)
|
||||
public void ChangeBitDepth(byte[] depth)
|
||||
{
|
||||
for(int i = 0; i< 4; i++)
|
||||
{
|
||||
int Value = ChangeBitDepth(GetComponent(i), BitDepth[i], Depth[i]);
|
||||
int value = ChangeBitDepth(GetComponent(i), _bitDepth[i], depth[i]);
|
||||
|
||||
SetComponent(i, Value);
|
||||
BitDepth[i] = Depth[i];
|
||||
SetComponent(i, value);
|
||||
_bitDepth[i] = depth[i];
|
||||
}
|
||||
}
|
||||
|
||||
short ChangeBitDepth(short Value, byte OldDepth, byte NewDepth)
|
||||
short ChangeBitDepth(short value, byte oldDepth, byte newDepth)
|
||||
{
|
||||
Debug.Assert(NewDepth <= 8);
|
||||
Debug.Assert(OldDepth <= 8);
|
||||
Debug.Assert(newDepth <= 8);
|
||||
Debug.Assert(oldDepth <= 8);
|
||||
|
||||
if (OldDepth == NewDepth)
|
||||
if (oldDepth == newDepth)
|
||||
{
|
||||
// Do nothing
|
||||
return Value;
|
||||
return value;
|
||||
}
|
||||
else if (OldDepth == 0 && NewDepth != 0)
|
||||
else if (oldDepth == 0 && newDepth != 0)
|
||||
{
|
||||
return (short)((1 << NewDepth) - 1);
|
||||
return (short)((1 << newDepth) - 1);
|
||||
}
|
||||
else if (NewDepth > OldDepth)
|
||||
else if (newDepth > oldDepth)
|
||||
{
|
||||
return (short)BitArrayStream.Replicate(Value, OldDepth, NewDepth);
|
||||
return (short)BitArrayStream.Replicate(value, oldDepth, newDepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
// oldDepth > newDepth
|
||||
if (NewDepth == 0)
|
||||
if (newDepth == 0)
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte BitsWasted = (byte)(OldDepth - NewDepth);
|
||||
short TempValue = Value;
|
||||
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));
|
||||
tempValue = (short)((tempValue + (1 << (bitsWasted - 1))) >> bitsWasted);
|
||||
tempValue = Math.Min(Math.Max((short)0, tempValue), (short)((1 << newDepth) - 1));
|
||||
|
||||
return (byte)(TempValue);
|
||||
return (byte)(tempValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Pack()
|
||||
{
|
||||
ASTCPixel NewPixel = new ASTCPixel(A, R, G, B);
|
||||
AstcPixel newPixel = new AstcPixel(A, R, G, B);
|
||||
byte[] eightBitDepth = { 8, 8, 8, 8 };
|
||||
|
||||
NewPixel.ChangeBitDepth(eightBitDepth);
|
||||
newPixel.ChangeBitDepth(eightBitDepth);
|
||||
|
||||
return (byte)NewPixel.A << 24 |
|
||||
(byte)NewPixel.B << 16 |
|
||||
(byte)NewPixel.G << 8 |
|
||||
(byte)NewPixel.R << 0;
|
||||
return (byte)newPixel.A << 24 |
|
||||
(byte)newPixel.B << 16 |
|
||||
(byte)newPixel.G << 8 |
|
||||
(byte)newPixel.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)
|
||||
public static AstcPixel BlueContract(int a, int r, int g, int b)
|
||||
{
|
||||
return new ASTCPixel((short)(a),
|
||||
return new AstcPixel((short)(a),
|
||||
(short)((r + b) >> 1),
|
||||
(short)((g + b) >> 1),
|
||||
(short)(b));
|
||||
|
|
|
@ -9,103 +9,103 @@ namespace Ryujinx.Graphics.Texture
|
|||
|
||||
public int Position { get; private set; }
|
||||
|
||||
public BitArrayStream(BitArray BitArray)
|
||||
public BitArrayStream(BitArray bitArray)
|
||||
{
|
||||
BitsArray = BitArray;
|
||||
BitsArray = bitArray;
|
||||
Position = 0;
|
||||
}
|
||||
|
||||
public short ReadBits(int Length)
|
||||
public short ReadBits(int length)
|
||||
{
|
||||
int RetValue = 0;
|
||||
for (int i = Position; i < Position + Length; i++)
|
||||
int retValue = 0;
|
||||
for (int i = Position; i < Position + length; i++)
|
||||
{
|
||||
if (BitsArray[i])
|
||||
{
|
||||
RetValue |= 1 << (i - Position);
|
||||
retValue |= 1 << (i - Position);
|
||||
}
|
||||
}
|
||||
|
||||
Position += Length;
|
||||
return (short)RetValue;
|
||||
Position += length;
|
||||
return (short)retValue;
|
||||
}
|
||||
|
||||
public int ReadBits(int Start, int End)
|
||||
public int ReadBits(int start, int end)
|
||||
{
|
||||
int RetValue = 0;
|
||||
for (int i = Start; i <= End; i++)
|
||||
int retValue = 0;
|
||||
for (int i = start; i <= end; i++)
|
||||
{
|
||||
if (BitsArray[i])
|
||||
{
|
||||
RetValue |= 1 << (i - Start);
|
||||
retValue |= 1 << (i - start);
|
||||
}
|
||||
}
|
||||
|
||||
return RetValue;
|
||||
return retValue;
|
||||
}
|
||||
|
||||
public int ReadBit(int Index)
|
||||
public int ReadBit(int index)
|
||||
{
|
||||
return Convert.ToInt32(BitsArray[Index]);
|
||||
return Convert.ToInt32(BitsArray[index]);
|
||||
}
|
||||
|
||||
public void WriteBits(int Value, int Length)
|
||||
public void WriteBits(int value, int length)
|
||||
{
|
||||
for (int i = Position; i < Position + Length; i++)
|
||||
for (int i = Position; i < Position + length; i++)
|
||||
{
|
||||
BitsArray[i] = ((Value >> (i - Position)) & 1) != 0;
|
||||
BitsArray[i] = ((value >> (i - Position)) & 1) != 0;
|
||||
}
|
||||
|
||||
Position += Length;
|
||||
Position += length;
|
||||
}
|
||||
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
byte[] RetArray = new byte[(BitsArray.Length + 7) / 8];
|
||||
BitsArray.CopyTo(RetArray, 0);
|
||||
return RetArray;
|
||||
byte[] retArray = new byte[(BitsArray.Length + 7) / 8];
|
||||
BitsArray.CopyTo(retArray, 0);
|
||||
return retArray;
|
||||
}
|
||||
|
||||
public static int Replicate(int Value, int NumberBits, int ToBit)
|
||||
public static int Replicate(int value, int numberBits, int toBit)
|
||||
{
|
||||
if (NumberBits == 0) return 0;
|
||||
if (ToBit == 0) return 0;
|
||||
if (numberBits == 0) return 0;
|
||||
if (toBit == 0) return 0;
|
||||
|
||||
int TempValue = Value & ((1 << NumberBits) - 1);
|
||||
int RetValue = TempValue;
|
||||
int ResLength = NumberBits;
|
||||
int tempValue = value & ((1 << numberBits) - 1);
|
||||
int retValue = tempValue;
|
||||
int resLength = numberBits;
|
||||
|
||||
while (ResLength < ToBit)
|
||||
while (resLength < toBit)
|
||||
{
|
||||
int Comp = 0;
|
||||
if (NumberBits > ToBit - ResLength)
|
||||
int comp = 0;
|
||||
if (numberBits > toBit - resLength)
|
||||
{
|
||||
int NewShift = ToBit - ResLength;
|
||||
Comp = NumberBits - NewShift;
|
||||
NumberBits = NewShift;
|
||||
int newShift = toBit - resLength;
|
||||
comp = numberBits - newShift;
|
||||
numberBits = newShift;
|
||||
}
|
||||
RetValue <<= NumberBits;
|
||||
RetValue |= TempValue >> Comp;
|
||||
ResLength += NumberBits;
|
||||
retValue <<= numberBits;
|
||||
retValue |= tempValue >> comp;
|
||||
resLength += numberBits;
|
||||
}
|
||||
return RetValue;
|
||||
return retValue;
|
||||
}
|
||||
|
||||
public static int PopCnt(int Number)
|
||||
public static int PopCnt(int number)
|
||||
{
|
||||
int Counter;
|
||||
for (Counter = 0; Number != 0; Counter++)
|
||||
int counter;
|
||||
for (counter = 0; number != 0; counter++)
|
||||
{
|
||||
Number &= Number - 1;
|
||||
number &= number - 1;
|
||||
}
|
||||
return Counter;
|
||||
return counter;
|
||||
}
|
||||
|
||||
public static void Swap<T>(ref T lhs, ref T rhs)
|
||||
{
|
||||
T Temp = lhs;
|
||||
T temp = lhs;
|
||||
lhs = rhs;
|
||||
rhs = Temp;
|
||||
rhs = temp;
|
||||
}
|
||||
|
||||
// Transfers a bit as described in C.2.14
|
||||
|
|
|
@ -10,98 +10,98 @@ namespace Ryujinx.Graphics.Texture
|
|||
|
||||
private const int GobSize = GobWidth * GobHeight;
|
||||
|
||||
private int TexWidth;
|
||||
private int TexHeight;
|
||||
private int TexDepth;
|
||||
private int TexGobBlockHeight;
|
||||
private int TexGobBlockDepth;
|
||||
private int TexBpp;
|
||||
private int _texWidth;
|
||||
private int _texHeight;
|
||||
private int _texDepth;
|
||||
private int _texGobBlockHeight;
|
||||
private int _texGobBlockDepth;
|
||||
private int _texBpp;
|
||||
|
||||
private int BhMask;
|
||||
private int BdMask;
|
||||
private int _bhMask;
|
||||
private int _bdMask;
|
||||
|
||||
private int BhShift;
|
||||
private int BdShift;
|
||||
private int BppShift;
|
||||
private int _bhShift;
|
||||
private int _bdShift;
|
||||
private int _bppShift;
|
||||
|
||||
private int XShift;
|
||||
private int _xShift;
|
||||
|
||||
private int RobSize;
|
||||
private int SliceSize;
|
||||
private int _robSize;
|
||||
private int _sliceSize;
|
||||
|
||||
private int BaseOffset;
|
||||
private int _baseOffset;
|
||||
|
||||
public BlockLinearSwizzle(
|
||||
int Width,
|
||||
int Height,
|
||||
int Depth,
|
||||
int GobBlockHeight,
|
||||
int GobBlockDepth,
|
||||
int Bpp)
|
||||
int width,
|
||||
int height,
|
||||
int depth,
|
||||
int gobBlockHeight,
|
||||
int gobBlockDepth,
|
||||
int bpp)
|
||||
{
|
||||
TexWidth = Width;
|
||||
TexHeight = Height;
|
||||
TexDepth = Depth;
|
||||
TexGobBlockHeight = GobBlockHeight;
|
||||
TexGobBlockDepth = GobBlockDepth;
|
||||
TexBpp = Bpp;
|
||||
_texWidth = width;
|
||||
_texHeight = height;
|
||||
_texDepth = depth;
|
||||
_texGobBlockHeight = gobBlockHeight;
|
||||
_texGobBlockDepth = gobBlockDepth;
|
||||
_texBpp = bpp;
|
||||
|
||||
BppShift = BitUtils.CountTrailingZeros32(Bpp);
|
||||
_bppShift = BitUtils.CountTrailingZeros32(bpp);
|
||||
|
||||
SetMipLevel(0);
|
||||
}
|
||||
|
||||
public void SetMipLevel(int Level)
|
||||
public void SetMipLevel(int level)
|
||||
{
|
||||
BaseOffset = GetMipOffset(Level);
|
||||
_baseOffset = GetMipOffset(level);
|
||||
|
||||
int Width = Math.Max(1, TexWidth >> Level);
|
||||
int Height = Math.Max(1, TexHeight >> Level);
|
||||
int Depth = Math.Max(1, TexDepth >> Level);
|
||||
int width = Math.Max(1, _texWidth >> level);
|
||||
int height = Math.Max(1, _texHeight >> level);
|
||||
int depth = Math.Max(1, _texDepth >> level);
|
||||
|
||||
GobBlockSizes GbSizes = AdjustGobBlockSizes(Height, Depth);
|
||||
GobBlockSizes gbSizes = AdjustGobBlockSizes(height, depth);
|
||||
|
||||
BhMask = GbSizes.Height - 1;
|
||||
BdMask = GbSizes.Depth - 1;
|
||||
_bhMask = gbSizes.Height - 1;
|
||||
_bdMask = gbSizes.Depth - 1;
|
||||
|
||||
BhShift = BitUtils.CountTrailingZeros32(GbSizes.Height);
|
||||
BdShift = BitUtils.CountTrailingZeros32(GbSizes.Depth);
|
||||
_bhShift = BitUtils.CountTrailingZeros32(gbSizes.Height);
|
||||
_bdShift = BitUtils.CountTrailingZeros32(gbSizes.Depth);
|
||||
|
||||
XShift = BitUtils.CountTrailingZeros32(GobSize * GbSizes.Height * GbSizes.Depth);
|
||||
_xShift = BitUtils.CountTrailingZeros32(GobSize * gbSizes.Height * gbSizes.Depth);
|
||||
|
||||
RobAndSliceSizes GsSizes = GetRobAndSliceSizes(Width, Height, GbSizes);
|
||||
RobAndSliceSizes gsSizes = GetRobAndSliceSizes(width, height, gbSizes);
|
||||
|
||||
RobSize = GsSizes.RobSize;
|
||||
SliceSize = GsSizes.SliceSize;
|
||||
_robSize = gsSizes.RobSize;
|
||||
_sliceSize = gsSizes.SliceSize;
|
||||
}
|
||||
|
||||
public int GetImageSize(int MipsCount)
|
||||
public int GetImageSize(int mipsCount)
|
||||
{
|
||||
int Size = GetMipOffset(MipsCount);
|
||||
int size = GetMipOffset(mipsCount);
|
||||
|
||||
Size = (Size + 0x1fff) & ~0x1fff;
|
||||
size = (size + 0x1fff) & ~0x1fff;
|
||||
|
||||
return Size;
|
||||
return size;
|
||||
}
|
||||
|
||||
public int GetMipOffset(int Level)
|
||||
public int GetMipOffset(int level)
|
||||
{
|
||||
int TotalSize = 0;
|
||||
int totalSize = 0;
|
||||
|
||||
for (int Index = 0; Index < Level; Index++)
|
||||
for (int index = 0; index < level; index++)
|
||||
{
|
||||
int Width = Math.Max(1, TexWidth >> Index);
|
||||
int Height = Math.Max(1, TexHeight >> Index);
|
||||
int Depth = Math.Max(1, TexDepth >> Index);
|
||||
int width = Math.Max(1, _texWidth >> index);
|
||||
int height = Math.Max(1, _texHeight >> index);
|
||||
int depth = Math.Max(1, _texDepth >> index);
|
||||
|
||||
GobBlockSizes GbSizes = AdjustGobBlockSizes(Height, Depth);
|
||||
GobBlockSizes gbSizes = AdjustGobBlockSizes(height, depth);
|
||||
|
||||
RobAndSliceSizes RsSizes = GetRobAndSliceSizes(Width, Height, GbSizes);
|
||||
RobAndSliceSizes rsSizes = GetRobAndSliceSizes(width, height, gbSizes);
|
||||
|
||||
TotalSize += BitUtils.DivRoundUp(Depth, GbSizes.Depth) * RsSizes.SliceSize;
|
||||
totalSize += BitUtils.DivRoundUp(depth, gbSizes.Depth) * rsSizes.SliceSize;
|
||||
}
|
||||
|
||||
return TotalSize;
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
private struct GobBlockSizes
|
||||
|
@ -109,32 +109,32 @@ namespace Ryujinx.Graphics.Texture
|
|||
public int Height;
|
||||
public int Depth;
|
||||
|
||||
public GobBlockSizes(int GobBlockHeight, int GobBlockDepth)
|
||||
public GobBlockSizes(int gobBlockHeight, int gobBlockDepth)
|
||||
{
|
||||
this.Height = GobBlockHeight;
|
||||
this.Depth = GobBlockDepth;
|
||||
this.Height = gobBlockHeight;
|
||||
this.Depth = gobBlockDepth;
|
||||
}
|
||||
}
|
||||
|
||||
private GobBlockSizes AdjustGobBlockSizes(int Height, int Depth)
|
||||
private GobBlockSizes AdjustGobBlockSizes(int height, int depth)
|
||||
{
|
||||
int GobBlockHeight = TexGobBlockHeight;
|
||||
int GobBlockDepth = TexGobBlockDepth;
|
||||
int gobBlockHeight = _texGobBlockHeight;
|
||||
int gobBlockDepth = _texGobBlockDepth;
|
||||
|
||||
int Pow2Height = BitUtils.Pow2RoundUp(Height);
|
||||
int Pow2Depth = BitUtils.Pow2RoundUp(Depth);
|
||||
int pow2Height = BitUtils.Pow2RoundUp(height);
|
||||
int pow2Depth = BitUtils.Pow2RoundUp(depth);
|
||||
|
||||
while (GobBlockHeight * GobHeight > Pow2Height && GobBlockHeight > 1)
|
||||
while (gobBlockHeight * GobHeight > pow2Height && gobBlockHeight > 1)
|
||||
{
|
||||
GobBlockHeight >>= 1;
|
||||
gobBlockHeight >>= 1;
|
||||
}
|
||||
|
||||
while (GobBlockDepth > Pow2Depth && GobBlockDepth > 1)
|
||||
while (gobBlockDepth > pow2Depth && gobBlockDepth > 1)
|
||||
{
|
||||
GobBlockDepth >>= 1;
|
||||
gobBlockDepth >>= 1;
|
||||
}
|
||||
|
||||
return new GobBlockSizes(GobBlockHeight, GobBlockDepth);
|
||||
return new GobBlockSizes(gobBlockHeight, gobBlockDepth);
|
||||
}
|
||||
|
||||
private struct RobAndSliceSizes
|
||||
|
@ -142,45 +142,45 @@ namespace Ryujinx.Graphics.Texture
|
|||
public int RobSize;
|
||||
public int SliceSize;
|
||||
|
||||
public RobAndSliceSizes(int RobSize, int SliceSize)
|
||||
public RobAndSliceSizes(int robSize, int sliceSize)
|
||||
{
|
||||
this.RobSize = RobSize;
|
||||
this.SliceSize = SliceSize;
|
||||
this.RobSize = robSize;
|
||||
this.SliceSize = sliceSize;
|
||||
}
|
||||
}
|
||||
|
||||
private RobAndSliceSizes GetRobAndSliceSizes(int Width, int Height, GobBlockSizes GbSizes)
|
||||
private RobAndSliceSizes GetRobAndSliceSizes(int width, int height, GobBlockSizes gbSizes)
|
||||
{
|
||||
int WidthInGobs = BitUtils.DivRoundUp(Width * TexBpp, GobWidth);
|
||||
int widthInGobs = BitUtils.DivRoundUp(width * _texBpp, GobWidth);
|
||||
|
||||
int RobSize = GobSize * GbSizes.Height * GbSizes.Depth * WidthInGobs;
|
||||
int robSize = GobSize * gbSizes.Height * gbSizes.Depth * widthInGobs;
|
||||
|
||||
int SliceSize = BitUtils.DivRoundUp(Height, GbSizes.Height * GobHeight) * RobSize;
|
||||
int sliceSize = BitUtils.DivRoundUp(height, gbSizes.Height * GobHeight) * robSize;
|
||||
|
||||
return new RobAndSliceSizes(RobSize, SliceSize);
|
||||
return new RobAndSliceSizes(robSize, sliceSize);
|
||||
}
|
||||
|
||||
public int GetSwizzleOffset(int X, int Y, int Z)
|
||||
public int GetSwizzleOffset(int x, int y, int z)
|
||||
{
|
||||
X <<= BppShift;
|
||||
x <<= _bppShift;
|
||||
|
||||
int YH = Y / GobHeight;
|
||||
int yh = y / GobHeight;
|
||||
|
||||
int Position = (Z >> BdShift) * SliceSize + (YH >> BhShift) * RobSize;
|
||||
int position = (z >> _bdShift) * _sliceSize + (yh >> _bhShift) * _robSize;
|
||||
|
||||
Position += (X / GobWidth) << XShift;
|
||||
position += (x / GobWidth) << _xShift;
|
||||
|
||||
Position += (YH & BhMask) * GobSize;
|
||||
position += (yh & _bhMask) * GobSize;
|
||||
|
||||
Position += ((Z & BdMask) * GobSize) << BhShift;
|
||||
position += ((z & _bdMask) * GobSize) << _bhShift;
|
||||
|
||||
Position += ((X & 0x3f) >> 5) << 8;
|
||||
Position += ((Y & 0x07) >> 1) << 6;
|
||||
Position += ((X & 0x1f) >> 4) << 5;
|
||||
Position += ((Y & 0x01) >> 0) << 4;
|
||||
Position += ((X & 0x0f) >> 0) << 0;
|
||||
position += ((x & 0x3f) >> 5) << 8;
|
||||
position += ((y & 0x07) >> 1) << 6;
|
||||
position += ((x & 0x1f) >> 4) << 5;
|
||||
position += ((y & 0x01) >> 0) << 4;
|
||||
position += ((x & 0x0f) >> 0) << 0;
|
||||
|
||||
return BaseOffset + Position;
|
||||
return _baseOffset + position;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,12 +2,12 @@ namespace Ryujinx.Graphics.Texture
|
|||
{
|
||||
interface ISwizzle
|
||||
{
|
||||
int GetSwizzleOffset(int X, int Y, int Z);
|
||||
int GetSwizzleOffset(int x, int y, int z);
|
||||
|
||||
void SetMipLevel(int Level);
|
||||
void SetMipLevel(int level);
|
||||
|
||||
int GetMipOffset(int Level);
|
||||
int GetMipOffset(int level);
|
||||
|
||||
int GetImageSize(int MipsCount);
|
||||
int GetImageSize(int mipsCount);
|
||||
}
|
||||
}
|
|
@ -29,13 +29,13 @@ namespace Ryujinx.Graphics.Texture
|
|||
|
||||
public TargetBuffer Target { get; private set; }
|
||||
|
||||
public ImageDescriptor(int BytesPerPixel, int BlockWidth, int BlockHeight, int BlockDepth, TargetBuffer Target)
|
||||
public ImageDescriptor(int bytesPerPixel, int blockWidth, int blockHeight, int blockDepth, TargetBuffer target)
|
||||
{
|
||||
this.BytesPerPixel = BytesPerPixel;
|
||||
this.BlockWidth = BlockWidth;
|
||||
this.BlockHeight = BlockHeight;
|
||||
this.BlockDepth = BlockDepth;
|
||||
this.Target = Target;
|
||||
this.BytesPerPixel = bytesPerPixel;
|
||||
this.BlockWidth = blockWidth;
|
||||
this.BlockHeight = blockHeight;
|
||||
this.BlockDepth = blockDepth;
|
||||
this.Target = target;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Texture
|
|||
private const GalImageFormat Float = GalImageFormat.Float;
|
||||
private const GalImageFormat Srgb = GalImageFormat.Srgb;
|
||||
|
||||
private static readonly Dictionary<GalTextureFormat, GalImageFormat> s_TextureTable =
|
||||
private static readonly Dictionary<GalTextureFormat, GalImageFormat> TextureTable =
|
||||
new Dictionary<GalTextureFormat, GalImageFormat>()
|
||||
{
|
||||
{ GalTextureFormat.RGBA32, GalImageFormat.RGBA32 | Sint | Uint | Float },
|
||||
|
@ -93,7 +93,7 @@ namespace Ryujinx.Graphics.Texture
|
|||
{ GalTextureFormat.Astc2D10x6, GalImageFormat.Astc2D10x6 | Unorm | Srgb }
|
||||
};
|
||||
|
||||
private static readonly Dictionary<GalImageFormat, ImageDescriptor> s_ImageTable =
|
||||
private static readonly Dictionary<GalImageFormat, ImageDescriptor> ImageTable =
|
||||
new Dictionary<GalImageFormat, ImageDescriptor>()
|
||||
{
|
||||
{ GalImageFormat.RGBA32, new ImageDescriptor(16, 1, 1, 1, TargetBuffer.Color) },
|
||||
|
@ -145,38 +145,38 @@ namespace Ryujinx.Graphics.Texture
|
|||
};
|
||||
|
||||
public static GalImageFormat ConvertTexture(
|
||||
GalTextureFormat Format,
|
||||
GalTextureType RType,
|
||||
GalTextureType GType,
|
||||
GalTextureType BType,
|
||||
GalTextureType AType,
|
||||
bool ConvSrgb)
|
||||
GalTextureFormat format,
|
||||
GalTextureType rType,
|
||||
GalTextureType gType,
|
||||
GalTextureType bType,
|
||||
GalTextureType aType,
|
||||
bool convSrgb)
|
||||
{
|
||||
if (!s_TextureTable.TryGetValue(Format, out GalImageFormat ImageFormat))
|
||||
if (!TextureTable.TryGetValue(format, out GalImageFormat imageFormat))
|
||||
{
|
||||
throw new NotImplementedException($"Format 0x{((int)Format):x} not implemented!");
|
||||
throw new NotImplementedException($"Format 0x{((int)format):x} not implemented!");
|
||||
}
|
||||
|
||||
if (!HasDepth(ImageFormat) && (RType != GType || RType != BType || RType != AType))
|
||||
if (!HasDepth(imageFormat) && (rType != gType || rType != bType || rType != aType))
|
||||
{
|
||||
throw new NotImplementedException($"Per component types are not implemented!");
|
||||
}
|
||||
|
||||
GalImageFormat FormatType = ConvSrgb ? Srgb : GetFormatType(RType);
|
||||
GalImageFormat formatType = convSrgb ? Srgb : GetFormatType(rType);
|
||||
|
||||
GalImageFormat CombinedFormat = (ImageFormat & GalImageFormat.FormatMask) | FormatType;
|
||||
GalImageFormat combinedFormat = (imageFormat & GalImageFormat.FormatMask) | formatType;
|
||||
|
||||
if (!ImageFormat.HasFlag(FormatType))
|
||||
if (!imageFormat.HasFlag(formatType))
|
||||
{
|
||||
throw new NotImplementedException($"Format \"{CombinedFormat}\" not implemented!");
|
||||
throw new NotImplementedException($"Format \"{combinedFormat}\" not implemented!");
|
||||
}
|
||||
|
||||
return CombinedFormat;
|
||||
return combinedFormat;
|
||||
}
|
||||
|
||||
public static GalImageFormat ConvertSurface(GalSurfaceFormat Format)
|
||||
public static GalImageFormat ConvertSurface(GalSurfaceFormat format)
|
||||
{
|
||||
switch (Format)
|
||||
switch (format)
|
||||
{
|
||||
case GalSurfaceFormat.RGBA32Float: return GalImageFormat.RGBA32 | Float;
|
||||
case GalSurfaceFormat.RGBA32Uint: return GalImageFormat.RGBA32 | Uint;
|
||||
|
@ -210,12 +210,12 @@ namespace Ryujinx.Graphics.Texture
|
|||
case GalSurfaceFormat.RGBX8Unorm: return GalImageFormat.RGBX8 | Unorm;
|
||||
}
|
||||
|
||||
throw new NotImplementedException(Format.ToString());
|
||||
throw new NotImplementedException(format.ToString());
|
||||
}
|
||||
|
||||
public static GalImageFormat ConvertZeta(GalZetaFormat Format)
|
||||
public static GalImageFormat ConvertZeta(GalZetaFormat format)
|
||||
{
|
||||
switch (Format)
|
||||
switch (format)
|
||||
{
|
||||
case GalZetaFormat.D32Float: return GalImageFormat.D32 | Float;
|
||||
case GalZetaFormat.S8D24Unorm: return GalImageFormat.D24S8 | Unorm;
|
||||
|
@ -225,268 +225,268 @@ namespace Ryujinx.Graphics.Texture
|
|||
case GalZetaFormat.D32S8X24Float: return GalImageFormat.D32S8 | Float;
|
||||
}
|
||||
|
||||
throw new NotImplementedException(Format.ToString());
|
||||
throw new NotImplementedException(format.ToString());
|
||||
}
|
||||
|
||||
public static byte[] ReadTexture(IMemory Memory, GalImage Image, long Position)
|
||||
public static byte[] ReadTexture(IMemory memory, GalImage image, long position)
|
||||
{
|
||||
MemoryManager CpuMemory;
|
||||
MemoryManager cpuMemory;
|
||||
|
||||
if (Memory is NvGpuVmm Vmm)
|
||||
if (memory is NvGpuVmm vmm)
|
||||
{
|
||||
CpuMemory = Vmm.Memory;
|
||||
cpuMemory = vmm.Memory;
|
||||
}
|
||||
else
|
||||
{
|
||||
CpuMemory = (MemoryManager)Memory;
|
||||
cpuMemory = (MemoryManager)memory;
|
||||
}
|
||||
|
||||
ISwizzle Swizzle = TextureHelper.GetSwizzle(Image);
|
||||
ISwizzle swizzle = TextureHelper.GetSwizzle(image);
|
||||
|
||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||
ImageDescriptor desc = GetImageDescriptor(image.Format);
|
||||
|
||||
(int Width, int Height, int Depth) = GetImageSizeInBlocks(Image);
|
||||
(int width, int height, int depth) = GetImageSizeInBlocks(image);
|
||||
|
||||
int BytesPerPixel = Desc.BytesPerPixel;
|
||||
int bytesPerPixel = desc.BytesPerPixel;
|
||||
|
||||
//Note: Each row of the texture needs to be aligned to 4 bytes.
|
||||
int Pitch = (Width * BytesPerPixel + 3) & ~3;
|
||||
int pitch = (width * bytesPerPixel + 3) & ~3;
|
||||
|
||||
|
||||
int DataLayerSize = Height * Pitch * Depth;
|
||||
byte[] Data = new byte[DataLayerSize * Image.LayerCount];
|
||||
int dataLayerSize = height * pitch * depth;
|
||||
byte[] data = new byte[dataLayerSize * image.LayerCount];
|
||||
|
||||
int TargetMipLevel = Image.MaxMipmapLevel <= 1 ? 1 : Image.MaxMipmapLevel - 1;
|
||||
int LayerOffset = ImageUtils.GetLayerOffset(Image, TargetMipLevel);
|
||||
int targetMipLevel = image.MaxMipmapLevel <= 1 ? 1 : image.MaxMipmapLevel - 1;
|
||||
int layerOffset = ImageUtils.GetLayerOffset(image, targetMipLevel);
|
||||
|
||||
for (int Layer = 0; Layer < Image.LayerCount; Layer++)
|
||||
for (int layer = 0; layer < image.LayerCount; layer++)
|
||||
{
|
||||
for (int Z = 0; Z < Depth; Z++)
|
||||
for (int z = 0; z < depth; z++)
|
||||
{
|
||||
for (int Y = 0; Y < Height; Y++)
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
int OutOffs = (DataLayerSize * Layer) + Y * Pitch + (Z * Width * Height * BytesPerPixel);
|
||||
int outOffs = (dataLayerSize * layer) + y * pitch + (z * width * height * bytesPerPixel);
|
||||
|
||||
for (int X = 0; X < Width; X++)
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y, Z);
|
||||
long offset = (uint)swizzle.GetSwizzleOffset(x, y, z);
|
||||
|
||||
CpuMemory.ReadBytes(Position + (LayerOffset * Layer) + Offset, Data, OutOffs, BytesPerPixel);
|
||||
cpuMemory.ReadBytes(position + (layerOffset * layer) + offset, data, outOffs, bytesPerPixel);
|
||||
|
||||
OutOffs += BytesPerPixel;
|
||||
outOffs += bytesPerPixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Data;
|
||||
return data;
|
||||
}
|
||||
|
||||
public static void WriteTexture(NvGpuVmm Vmm, GalImage Image, long Position, byte[] Data)
|
||||
public static void WriteTexture(NvGpuVmm vmm, GalImage image, long position, byte[] data)
|
||||
{
|
||||
ISwizzle Swizzle = TextureHelper.GetSwizzle(Image);
|
||||
ISwizzle swizzle = TextureHelper.GetSwizzle(image);
|
||||
|
||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||
ImageDescriptor desc = GetImageDescriptor(image.Format);
|
||||
|
||||
(int Width, int Height, int Depth) = ImageUtils.GetImageSizeInBlocks(Image);
|
||||
(int width, int height, int depth) = ImageUtils.GetImageSizeInBlocks(image);
|
||||
|
||||
int BytesPerPixel = Desc.BytesPerPixel;
|
||||
int bytesPerPixel = desc.BytesPerPixel;
|
||||
|
||||
int InOffs = 0;
|
||||
int inOffs = 0;
|
||||
|
||||
for (int Z = 0; Z < Depth; Z++)
|
||||
for (int Y = 0; Y < Height; Y++)
|
||||
for (int X = 0; X < Width; X++)
|
||||
for (int z = 0; z < depth; z++)
|
||||
for (int y = 0; y < height; y++)
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y, Z);
|
||||
long offset = (uint)swizzle.GetSwizzleOffset(x, y, z);
|
||||
|
||||
Vmm.Memory.WriteBytes(Position + Offset, Data, InOffs, BytesPerPixel);
|
||||
vmm.Memory.WriteBytes(position + offset, data, inOffs, bytesPerPixel);
|
||||
|
||||
InOffs += BytesPerPixel;
|
||||
inOffs += bytesPerPixel;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Support non 2D
|
||||
public static bool CopyTexture(
|
||||
NvGpuVmm Vmm,
|
||||
GalImage SrcImage,
|
||||
GalImage DstImage,
|
||||
long SrcAddress,
|
||||
long DstAddress,
|
||||
int SrcX,
|
||||
int SrcY,
|
||||
int DstX,
|
||||
int DstY,
|
||||
int Width,
|
||||
int Height)
|
||||
NvGpuVmm vmm,
|
||||
GalImage srcImage,
|
||||
GalImage dstImage,
|
||||
long srcAddress,
|
||||
long dstAddress,
|
||||
int srcX,
|
||||
int srcY,
|
||||
int dstX,
|
||||
int dstY,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
ISwizzle SrcSwizzle = TextureHelper.GetSwizzle(SrcImage);
|
||||
ISwizzle DstSwizzle = TextureHelper.GetSwizzle(DstImage);
|
||||
ISwizzle srcSwizzle = TextureHelper.GetSwizzle(srcImage);
|
||||
ISwizzle dstSwizzle = TextureHelper.GetSwizzle(dstImage);
|
||||
|
||||
ImageDescriptor Desc = GetImageDescriptor(SrcImage.Format);
|
||||
ImageDescriptor desc = GetImageDescriptor(srcImage.Format);
|
||||
|
||||
if (GetImageDescriptor(DstImage.Format).BytesPerPixel != Desc.BytesPerPixel)
|
||||
if (GetImageDescriptor(dstImage.Format).BytesPerPixel != desc.BytesPerPixel)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int BytesPerPixel = Desc.BytesPerPixel;
|
||||
int bytesPerPixel = desc.BytesPerPixel;
|
||||
|
||||
for (int Y = 0; Y < Height; Y++)
|
||||
for (int X = 0; X < Width; X++)
|
||||
for (int y = 0; y < height; y++)
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
long SrcOffset = (uint)SrcSwizzle.GetSwizzleOffset(SrcX + X, SrcY + Y, 0);
|
||||
long DstOffset = (uint)DstSwizzle.GetSwizzleOffset(DstX + X, DstY + Y, 0);
|
||||
long srcOffset = (uint)srcSwizzle.GetSwizzleOffset(srcX + x, srcY + y, 0);
|
||||
long dstOffset = (uint)dstSwizzle.GetSwizzleOffset(dstX + x, dstY + y, 0);
|
||||
|
||||
byte[] Texel = Vmm.ReadBytes(SrcAddress + SrcOffset, BytesPerPixel);
|
||||
byte[] texel = vmm.ReadBytes(srcAddress + srcOffset, bytesPerPixel);
|
||||
|
||||
Vmm.WriteBytes(DstAddress + DstOffset, Texel);
|
||||
vmm.WriteBytes(dstAddress + dstOffset, texel);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int GetSize(GalImage Image)
|
||||
public static int GetSize(GalImage image)
|
||||
{
|
||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||
ImageDescriptor desc = GetImageDescriptor(image.Format);
|
||||
|
||||
int ComponentCount = GetCoordsCountTextureTarget(Image.TextureTarget);
|
||||
int componentCount = GetCoordsCountTextureTarget(image.TextureTarget);
|
||||
|
||||
if (IsArray(Image.TextureTarget))
|
||||
ComponentCount--;
|
||||
if (IsArray(image.TextureTarget))
|
||||
componentCount--;
|
||||
|
||||
int Width = DivRoundUp(Image.Width, Desc.BlockWidth);
|
||||
int Height = DivRoundUp(Image.Height, Desc.BlockHeight);
|
||||
int Depth = DivRoundUp(Image.Depth, Desc.BlockDepth);
|
||||
int width = DivRoundUp(image.Width, desc.BlockWidth);
|
||||
int height = DivRoundUp(image.Height, desc.BlockHeight);
|
||||
int depth = DivRoundUp(image.Depth, desc.BlockDepth);
|
||||
|
||||
switch (ComponentCount)
|
||||
switch (componentCount)
|
||||
{
|
||||
case 1:
|
||||
return Desc.BytesPerPixel * Width * Image.LayerCount;
|
||||
return desc.BytesPerPixel * width * image.LayerCount;
|
||||
case 2:
|
||||
return Desc.BytesPerPixel * Width * Height * Image.LayerCount;
|
||||
return desc.BytesPerPixel * width * height * image.LayerCount;
|
||||
case 3:
|
||||
return Desc.BytesPerPixel * Width * Height * Depth * Image.LayerCount;
|
||||
return desc.BytesPerPixel * width * height * depth * image.LayerCount;
|
||||
default:
|
||||
throw new InvalidOperationException($"Invalid component count: {ComponentCount}");
|
||||
throw new InvalidOperationException($"Invalid component count: {componentCount}");
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetGpuSize(GalImage Image, bool forcePitch = false)
|
||||
public static int GetGpuSize(GalImage image, bool forcePitch = false)
|
||||
{
|
||||
return TextureHelper.GetSwizzle(Image).GetImageSize(Image.MaxMipmapLevel) * Image.LayerCount;
|
||||
return TextureHelper.GetSwizzle(image).GetImageSize(image.MaxMipmapLevel) * image.LayerCount;
|
||||
}
|
||||
|
||||
public static int GetLayerOffset(GalImage Image, int MipLevel)
|
||||
public static int GetLayerOffset(GalImage image, int mipLevel)
|
||||
{
|
||||
if (MipLevel <= 0)
|
||||
if (mipLevel <= 0)
|
||||
{
|
||||
MipLevel = 1;
|
||||
mipLevel = 1;
|
||||
}
|
||||
|
||||
return TextureHelper.GetSwizzle(Image).GetMipOffset(MipLevel);
|
||||
return TextureHelper.GetSwizzle(image).GetMipOffset(mipLevel);
|
||||
}
|
||||
|
||||
public static int GetPitch(GalImageFormat Format, int Width)
|
||||
public static int GetPitch(GalImageFormat format, int width)
|
||||
{
|
||||
ImageDescriptor Desc = GetImageDescriptor(Format);
|
||||
ImageDescriptor desc = GetImageDescriptor(format);
|
||||
|
||||
int Pitch = Desc.BytesPerPixel * DivRoundUp(Width, Desc.BlockWidth);
|
||||
int pitch = desc.BytesPerPixel * DivRoundUp(width, desc.BlockWidth);
|
||||
|
||||
Pitch = (Pitch + 0x1f) & ~0x1f;
|
||||
pitch = (pitch + 0x1f) & ~0x1f;
|
||||
|
||||
return Pitch;
|
||||
return pitch;
|
||||
}
|
||||
|
||||
public static int GetBlockWidth(GalImageFormat Format)
|
||||
public static int GetBlockWidth(GalImageFormat format)
|
||||
{
|
||||
return GetImageDescriptor(Format).BlockWidth;
|
||||
return GetImageDescriptor(format).BlockWidth;
|
||||
}
|
||||
|
||||
public static int GetBlockHeight(GalImageFormat Format)
|
||||
public static int GetBlockHeight(GalImageFormat format)
|
||||
{
|
||||
return GetImageDescriptor(Format).BlockHeight;
|
||||
return GetImageDescriptor(format).BlockHeight;
|
||||
}
|
||||
|
||||
public static int GetBlockDepth(GalImageFormat Format)
|
||||
public static int GetBlockDepth(GalImageFormat format)
|
||||
{
|
||||
return GetImageDescriptor(Format).BlockDepth;
|
||||
return GetImageDescriptor(format).BlockDepth;
|
||||
}
|
||||
|
||||
public static int GetAlignedWidth(GalImage Image)
|
||||
public static int GetAlignedWidth(GalImage image)
|
||||
{
|
||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||
ImageDescriptor desc = GetImageDescriptor(image.Format);
|
||||
|
||||
int AlignMask;
|
||||
int alignMask;
|
||||
|
||||
if (Image.Layout == GalMemoryLayout.BlockLinear)
|
||||
if (image.Layout == GalMemoryLayout.BlockLinear)
|
||||
{
|
||||
AlignMask = Image.TileWidth * (64 / Desc.BytesPerPixel) - 1;
|
||||
alignMask = image.TileWidth * (64 / desc.BytesPerPixel) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
AlignMask = (32 / Desc.BytesPerPixel) - 1;
|
||||
alignMask = (32 / desc.BytesPerPixel) - 1;
|
||||
}
|
||||
|
||||
return (Image.Width + AlignMask) & ~AlignMask;
|
||||
return (image.Width + alignMask) & ~alignMask;
|
||||
}
|
||||
|
||||
public static (int Width, int Height, int Depth) GetImageSizeInBlocks(GalImage Image)
|
||||
public static (int Width, int Height, int Depth) GetImageSizeInBlocks(GalImage image)
|
||||
{
|
||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||
ImageDescriptor desc = GetImageDescriptor(image.Format);
|
||||
|
||||
return (DivRoundUp(Image.Width, Desc.BlockWidth),
|
||||
DivRoundUp(Image.Height, Desc.BlockHeight),
|
||||
DivRoundUp(Image.Depth, Desc.BlockDepth));
|
||||
return (DivRoundUp(image.Width, desc.BlockWidth),
|
||||
DivRoundUp(image.Height, desc.BlockHeight),
|
||||
DivRoundUp(image.Depth, desc.BlockDepth));
|
||||
}
|
||||
|
||||
public static int GetBytesPerPixel(GalImageFormat Format)
|
||||
public static int GetBytesPerPixel(GalImageFormat format)
|
||||
{
|
||||
return GetImageDescriptor(Format).BytesPerPixel;
|
||||
return GetImageDescriptor(format).BytesPerPixel;
|
||||
}
|
||||
|
||||
private static int DivRoundUp(int LHS, int RHS)
|
||||
private static int DivRoundUp(int lhs, int rhs)
|
||||
{
|
||||
return (LHS + (RHS - 1)) / RHS;
|
||||
return (lhs + (rhs - 1)) / rhs;
|
||||
}
|
||||
|
||||
public static bool HasColor(GalImageFormat Format)
|
||||
public static bool HasColor(GalImageFormat format)
|
||||
{
|
||||
return (GetImageDescriptor(Format).Target & TargetBuffer.Color) != 0;
|
||||
return (GetImageDescriptor(format).Target & TargetBuffer.Color) != 0;
|
||||
}
|
||||
|
||||
public static bool HasDepth(GalImageFormat Format)
|
||||
public static bool HasDepth(GalImageFormat format)
|
||||
{
|
||||
return (GetImageDescriptor(Format).Target & TargetBuffer.Depth) != 0;
|
||||
return (GetImageDescriptor(format).Target & TargetBuffer.Depth) != 0;
|
||||
}
|
||||
|
||||
public static bool HasStencil(GalImageFormat Format)
|
||||
public static bool HasStencil(GalImageFormat format)
|
||||
{
|
||||
return (GetImageDescriptor(Format).Target & TargetBuffer.Stencil) != 0;
|
||||
return (GetImageDescriptor(format).Target & TargetBuffer.Stencil) != 0;
|
||||
}
|
||||
|
||||
public static bool IsCompressed(GalImageFormat Format)
|
||||
public static bool IsCompressed(GalImageFormat format)
|
||||
{
|
||||
ImageDescriptor Desc = GetImageDescriptor(Format);
|
||||
ImageDescriptor desc = GetImageDescriptor(format);
|
||||
|
||||
return (Desc.BlockWidth | Desc.BlockHeight) != 1;
|
||||
return (desc.BlockWidth | desc.BlockHeight) != 1;
|
||||
}
|
||||
|
||||
private static ImageDescriptor GetImageDescriptor(GalImageFormat Format)
|
||||
private static ImageDescriptor GetImageDescriptor(GalImageFormat format)
|
||||
{
|
||||
GalImageFormat PixelFormat = Format & GalImageFormat.FormatMask;
|
||||
GalImageFormat pixelFormat = format & GalImageFormat.FormatMask;
|
||||
|
||||
if (s_ImageTable.TryGetValue(PixelFormat, out ImageDescriptor Descriptor))
|
||||
if (ImageTable.TryGetValue(pixelFormat, out ImageDescriptor descriptor))
|
||||
{
|
||||
return Descriptor;
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
throw new NotImplementedException($"Format \"{PixelFormat}\" not implemented!");
|
||||
throw new NotImplementedException($"Format \"{pixelFormat}\" not implemented!");
|
||||
}
|
||||
|
||||
private static GalImageFormat GetFormatType(GalTextureType Type)
|
||||
private static GalImageFormat GetFormatType(GalTextureType type)
|
||||
{
|
||||
switch (Type)
|
||||
switch (type)
|
||||
{
|
||||
case GalTextureType.Snorm: return Snorm;
|
||||
case GalTextureType.Unorm: return Unorm;
|
||||
|
@ -494,13 +494,13 @@ namespace Ryujinx.Graphics.Texture
|
|||
case GalTextureType.Uint: return Uint;
|
||||
case GalTextureType.Float: return Float;
|
||||
|
||||
default: throw new NotImplementedException(((int)Type).ToString());
|
||||
default: throw new NotImplementedException(((int)type).ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public static TextureTarget GetTextureTarget(GalTextureTarget GalTextureTarget)
|
||||
public static TextureTarget GetTextureTarget(GalTextureTarget galTextureTarget)
|
||||
{
|
||||
switch (GalTextureTarget)
|
||||
switch (galTextureTarget)
|
||||
{
|
||||
case GalTextureTarget.OneD:
|
||||
return TextureTarget.Texture1D;
|
||||
|
@ -520,13 +520,13 @@ namespace Ryujinx.Graphics.Texture
|
|||
case GalTextureTarget.CubeArray:
|
||||
return TextureTarget.TextureCubeMapArray;
|
||||
default:
|
||||
throw new NotSupportedException($"Texture target {GalTextureTarget} currently not supported!");
|
||||
throw new NotSupportedException($"Texture target {galTextureTarget} currently not supported!");
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsArray(GalTextureTarget TextureTarget)
|
||||
public static bool IsArray(GalTextureTarget textureTarget)
|
||||
{
|
||||
switch (TextureTarget)
|
||||
switch (textureTarget)
|
||||
{
|
||||
case GalTextureTarget.OneDArray:
|
||||
case GalTextureTarget.TwoDArray:
|
||||
|
@ -537,9 +537,9 @@ namespace Ryujinx.Graphics.Texture
|
|||
}
|
||||
}
|
||||
|
||||
public static int GetCoordsCountTextureTarget(GalTextureTarget TextureTarget)
|
||||
public static int GetCoordsCountTextureTarget(GalTextureTarget textureTarget)
|
||||
{
|
||||
switch (TextureTarget)
|
||||
switch (textureTarget)
|
||||
{
|
||||
case GalTextureTarget.OneD:
|
||||
return 1;
|
||||
|
@ -555,7 +555,7 @@ namespace Ryujinx.Graphics.Texture
|
|||
case GalTextureTarget.CubeArray:
|
||||
return 4;
|
||||
default:
|
||||
throw new NotImplementedException($"TextureTarget.{TextureTarget} not implemented yet.");
|
||||
throw new NotImplementedException($"TextureTarget.{textureTarget} not implemented yet.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,81 +12,81 @@ namespace Ryujinx.Graphics.Texture
|
|||
Trit
|
||||
}
|
||||
|
||||
EIntegerEncoding Encoding;
|
||||
EIntegerEncoding _encoding;
|
||||
public int NumberBits { get; private set; }
|
||||
public int BitValue { get; private set; }
|
||||
public int TritValue { get; private set; }
|
||||
public int QuintValue { get; private set; }
|
||||
|
||||
public IntegerEncoded(EIntegerEncoding _Encoding, int NumBits)
|
||||
public IntegerEncoded(EIntegerEncoding encoding, int numBits)
|
||||
{
|
||||
Encoding = _Encoding;
|
||||
NumberBits = NumBits;
|
||||
_encoding = encoding;
|
||||
NumberBits = numBits;
|
||||
BitValue = 0;
|
||||
TritValue = 0;
|
||||
QuintValue = 0;
|
||||
}
|
||||
|
||||
public bool MatchesEncoding(IntegerEncoded Other)
|
||||
public bool MatchesEncoding(IntegerEncoded other)
|
||||
{
|
||||
return Encoding == Other.Encoding && NumberBits == Other.NumberBits;
|
||||
return _encoding == other._encoding && NumberBits == other.NumberBits;
|
||||
}
|
||||
|
||||
public EIntegerEncoding GetEncoding()
|
||||
{
|
||||
return Encoding;
|
||||
return _encoding;
|
||||
}
|
||||
|
||||
public int GetBitLength(int NumberVals)
|
||||
public int GetBitLength(int numberVals)
|
||||
{
|
||||
int TotalBits = NumberBits * NumberVals;
|
||||
if (Encoding == EIntegerEncoding.Trit)
|
||||
int totalBits = NumberBits * numberVals;
|
||||
if (_encoding == EIntegerEncoding.Trit)
|
||||
{
|
||||
TotalBits += (NumberVals * 8 + 4) / 5;
|
||||
totalBits += (numberVals * 8 + 4) / 5;
|
||||
}
|
||||
else if (Encoding == EIntegerEncoding.Quint)
|
||||
else if (_encoding == EIntegerEncoding.Quint)
|
||||
{
|
||||
TotalBits += (NumberVals * 7 + 2) / 3;
|
||||
totalBits += (numberVals * 7 + 2) / 3;
|
||||
}
|
||||
return TotalBits;
|
||||
return totalBits;
|
||||
}
|
||||
|
||||
public static IntegerEncoded CreateEncoding(int MaxVal)
|
||||
public static IntegerEncoded CreateEncoding(int maxVal)
|
||||
{
|
||||
while (MaxVal > 0)
|
||||
while (maxVal > 0)
|
||||
{
|
||||
int Check = MaxVal + 1;
|
||||
int check = maxVal + 1;
|
||||
|
||||
// Is maxVal a power of two?
|
||||
if ((Check & (Check - 1)) == 0)
|
||||
if ((check & (check - 1)) == 0)
|
||||
{
|
||||
return new IntegerEncoded(EIntegerEncoding.JustBits, BitArrayStream.PopCnt(MaxVal));
|
||||
return new IntegerEncoded(EIntegerEncoding.JustBits, BitArrayStream.PopCnt(maxVal));
|
||||
}
|
||||
|
||||
// Is maxVal of the type 3*2^n - 1?
|
||||
if ((Check % 3 == 0) && ((Check / 3) & ((Check / 3) - 1)) == 0)
|
||||
if ((check % 3 == 0) && ((check / 3) & ((check / 3) - 1)) == 0)
|
||||
{
|
||||
return new IntegerEncoded(EIntegerEncoding.Trit, BitArrayStream.PopCnt(Check / 3 - 1));
|
||||
return new IntegerEncoded(EIntegerEncoding.Trit, BitArrayStream.PopCnt(check / 3 - 1));
|
||||
}
|
||||
|
||||
// Is maxVal of the type 5*2^n - 1?
|
||||
if ((Check % 5 == 0) && ((Check / 5) & ((Check / 5) - 1)) == 0)
|
||||
if ((check % 5 == 0) && ((check / 5) & ((check / 5) - 1)) == 0)
|
||||
{
|
||||
return new IntegerEncoded(EIntegerEncoding.Quint, BitArrayStream.PopCnt(Check / 5 - 1));
|
||||
return new IntegerEncoded(EIntegerEncoding.Quint, BitArrayStream.PopCnt(check / 5 - 1));
|
||||
}
|
||||
|
||||
// Apparently it can't be represented with a bounded integer sequence...
|
||||
// just iterate.
|
||||
MaxVal--;
|
||||
maxVal--;
|
||||
}
|
||||
|
||||
return new IntegerEncoded(EIntegerEncoding.JustBits, 0);
|
||||
}
|
||||
|
||||
public static void DecodeTritBlock(
|
||||
BitArrayStream BitStream,
|
||||
List<IntegerEncoded> ListIntegerEncoded,
|
||||
int NumberBitsPerValue)
|
||||
BitArrayStream bitStream,
|
||||
List<IntegerEncoded> listIntegerEncoded,
|
||||
int numberBitsPerValue)
|
||||
{
|
||||
// Implement the algorithm in section C.2.12
|
||||
int[] m = new int[5];
|
||||
|
@ -95,170 +95,170 @@ namespace Ryujinx.Graphics.Texture
|
|||
|
||||
// Read the trit encoded block according to
|
||||
// table C.2.14
|
||||
m[0] = BitStream.ReadBits(NumberBitsPerValue);
|
||||
T = BitStream.ReadBits(2);
|
||||
m[1] = BitStream.ReadBits(NumberBitsPerValue);
|
||||
T |= BitStream.ReadBits(2) << 2;
|
||||
m[2] = BitStream.ReadBits(NumberBitsPerValue);
|
||||
T |= BitStream.ReadBits(1) << 4;
|
||||
m[3] = BitStream.ReadBits(NumberBitsPerValue);
|
||||
T |= BitStream.ReadBits(2) << 5;
|
||||
m[4] = BitStream.ReadBits(NumberBitsPerValue);
|
||||
T |= BitStream.ReadBits(1) << 7;
|
||||
m[0] = bitStream.ReadBits(numberBitsPerValue);
|
||||
T = bitStream.ReadBits(2);
|
||||
m[1] = bitStream.ReadBits(numberBitsPerValue);
|
||||
T |= bitStream.ReadBits(2) << 2;
|
||||
m[2] = bitStream.ReadBits(numberBitsPerValue);
|
||||
T |= bitStream.ReadBits(1) << 4;
|
||||
m[3] = bitStream.ReadBits(numberBitsPerValue);
|
||||
T |= bitStream.ReadBits(2) << 5;
|
||||
m[4] = bitStream.ReadBits(numberBitsPerValue);
|
||||
T |= bitStream.ReadBits(1) << 7;
|
||||
|
||||
int C = 0;
|
||||
int c = 0;
|
||||
|
||||
BitArrayStream Tb = new BitArrayStream(new BitArray(new int[] { T }));
|
||||
if (Tb.ReadBits(2, 4) == 7)
|
||||
BitArrayStream tb = new BitArrayStream(new BitArray(new int[] { T }));
|
||||
if (tb.ReadBits(2, 4) == 7)
|
||||
{
|
||||
C = (Tb.ReadBits(5, 7) << 2) | Tb.ReadBits(0, 1);
|
||||
c = (tb.ReadBits(5, 7) << 2) | tb.ReadBits(0, 1);
|
||||
t[4] = t[3] = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
C = Tb.ReadBits(0, 4);
|
||||
if (Tb.ReadBits(5, 6) == 3)
|
||||
c = tb.ReadBits(0, 4);
|
||||
if (tb.ReadBits(5, 6) == 3)
|
||||
{
|
||||
t[4] = 2;
|
||||
t[3] = Tb.ReadBit(7);
|
||||
t[3] = tb.ReadBit(7);
|
||||
}
|
||||
else
|
||||
{
|
||||
t[4] = Tb.ReadBit(7);
|
||||
t[3] = Tb.ReadBits(5, 6);
|
||||
t[4] = tb.ReadBit(7);
|
||||
t[3] = tb.ReadBits(5, 6);
|
||||
}
|
||||
}
|
||||
|
||||
BitArrayStream Cb = new BitArrayStream(new BitArray(new int[] { C }));
|
||||
if (Cb.ReadBits(0, 1) == 3)
|
||||
BitArrayStream cb = new BitArrayStream(new BitArray(new int[] { c }));
|
||||
if (cb.ReadBits(0, 1) == 3)
|
||||
{
|
||||
t[2] = 2;
|
||||
t[1] = Cb.ReadBit(4);
|
||||
t[0] = (Cb.ReadBit(3) << 1) | (Cb.ReadBit(2) & ~Cb.ReadBit(3));
|
||||
t[1] = cb.ReadBit(4);
|
||||
t[0] = (cb.ReadBit(3) << 1) | (cb.ReadBit(2) & ~cb.ReadBit(3));
|
||||
}
|
||||
else if (Cb.ReadBits(2, 3) == 3)
|
||||
else if (cb.ReadBits(2, 3) == 3)
|
||||
{
|
||||
t[2] = 2;
|
||||
t[1] = 2;
|
||||
t[0] = Cb.ReadBits(0, 1);
|
||||
t[0] = cb.ReadBits(0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
t[2] = Cb.ReadBit(4);
|
||||
t[1] = Cb.ReadBits(2, 3);
|
||||
t[0] = (Cb.ReadBit(1) << 1) | (Cb.ReadBit(0) & ~Cb.ReadBit(1));
|
||||
t[2] = cb.ReadBit(4);
|
||||
t[1] = cb.ReadBits(2, 3);
|
||||
t[0] = (cb.ReadBit(1) << 1) | (cb.ReadBit(0) & ~cb.ReadBit(1));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
IntegerEncoded IntEncoded = new IntegerEncoded(EIntegerEncoding.Trit, NumberBitsPerValue)
|
||||
IntegerEncoded intEncoded = new IntegerEncoded(EIntegerEncoding.Trit, numberBitsPerValue)
|
||||
{
|
||||
BitValue = m[i],
|
||||
TritValue = t[i]
|
||||
};
|
||||
ListIntegerEncoded.Add(IntEncoded);
|
||||
listIntegerEncoded.Add(intEncoded);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DecodeQuintBlock(
|
||||
BitArrayStream BitStream,
|
||||
List<IntegerEncoded> ListIntegerEncoded,
|
||||
int NumberBitsPerValue)
|
||||
BitArrayStream bitStream,
|
||||
List<IntegerEncoded> listIntegerEncoded,
|
||||
int numberBitsPerValue)
|
||||
{
|
||||
// Implement the algorithm in section C.2.12
|
||||
int[] m = new int[3];
|
||||
int[] qa = new int[3];
|
||||
int Q;
|
||||
int q;
|
||||
|
||||
// Read the trit encoded block according to
|
||||
// table C.2.15
|
||||
m[0] = BitStream.ReadBits(NumberBitsPerValue);
|
||||
Q = BitStream.ReadBits(3);
|
||||
m[1] = BitStream.ReadBits(NumberBitsPerValue);
|
||||
Q |= BitStream.ReadBits(2) << 3;
|
||||
m[2] = BitStream.ReadBits(NumberBitsPerValue);
|
||||
Q |= BitStream.ReadBits(2) << 5;
|
||||
m[0] = bitStream.ReadBits(numberBitsPerValue);
|
||||
q = bitStream.ReadBits(3);
|
||||
m[1] = bitStream.ReadBits(numberBitsPerValue);
|
||||
q |= bitStream.ReadBits(2) << 3;
|
||||
m[2] = bitStream.ReadBits(numberBitsPerValue);
|
||||
q |= bitStream.ReadBits(2) << 5;
|
||||
|
||||
BitArrayStream Qb = new BitArrayStream(new BitArray(new int[] { Q }));
|
||||
if (Qb.ReadBits(1, 2) == 3 && Qb.ReadBits(5, 6) == 0)
|
||||
BitArrayStream qb = new BitArrayStream(new BitArray(new int[] { q }));
|
||||
if (qb.ReadBits(1, 2) == 3 && qb.ReadBits(5, 6) == 0)
|
||||
{
|
||||
qa[0] = qa[1] = 4;
|
||||
qa[2] = (Qb.ReadBit(0) << 2) | ((Qb.ReadBit(4) & ~Qb.ReadBit(0)) << 1) | (Qb.ReadBit(3) & ~Qb.ReadBit(0));
|
||||
qa[2] = (qb.ReadBit(0) << 2) | ((qb.ReadBit(4) & ~qb.ReadBit(0)) << 1) | (qb.ReadBit(3) & ~qb.ReadBit(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
int C = 0;
|
||||
if (Qb.ReadBits(1, 2) == 3)
|
||||
int c = 0;
|
||||
if (qb.ReadBits(1, 2) == 3)
|
||||
{
|
||||
qa[2] = 4;
|
||||
C = (Qb.ReadBits(3, 4) << 3) | ((~Qb.ReadBits(5, 6) & 3) << 1) | Qb.ReadBit(0);
|
||||
c = (qb.ReadBits(3, 4) << 3) | ((~qb.ReadBits(5, 6) & 3) << 1) | qb.ReadBit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
qa[2] = Qb.ReadBits(5, 6);
|
||||
C = Qb.ReadBits(0, 4);
|
||||
qa[2] = qb.ReadBits(5, 6);
|
||||
c = qb.ReadBits(0, 4);
|
||||
}
|
||||
|
||||
BitArrayStream Cb = new BitArrayStream(new BitArray(new int[] { C }));
|
||||
if (Cb.ReadBits(0, 2) == 5)
|
||||
BitArrayStream cb = new BitArrayStream(new BitArray(new int[] { c }));
|
||||
if (cb.ReadBits(0, 2) == 5)
|
||||
{
|
||||
qa[1] = 4;
|
||||
qa[0] = Cb.ReadBits(3, 4);
|
||||
qa[0] = cb.ReadBits(3, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
qa[1] = Cb.ReadBits(3, 4);
|
||||
qa[0] = Cb.ReadBits(0, 2);
|
||||
qa[1] = cb.ReadBits(3, 4);
|
||||
qa[0] = cb.ReadBits(0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
IntegerEncoded IntEncoded = new IntegerEncoded(EIntegerEncoding.Quint, NumberBitsPerValue)
|
||||
IntegerEncoded intEncoded = new IntegerEncoded(EIntegerEncoding.Quint, numberBitsPerValue)
|
||||
{
|
||||
BitValue = m[i],
|
||||
QuintValue = qa[i]
|
||||
};
|
||||
ListIntegerEncoded.Add(IntEncoded);
|
||||
listIntegerEncoded.Add(intEncoded);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DecodeIntegerSequence(
|
||||
List<IntegerEncoded> DecodeIntegerSequence,
|
||||
BitArrayStream BitStream,
|
||||
int MaxRange,
|
||||
int NumberValues)
|
||||
List<IntegerEncoded> decodeIntegerSequence,
|
||||
BitArrayStream bitStream,
|
||||
int maxRange,
|
||||
int numberValues)
|
||||
{
|
||||
// Determine encoding parameters
|
||||
IntegerEncoded IntEncoded = CreateEncoding(MaxRange);
|
||||
IntegerEncoded intEncoded = CreateEncoding(maxRange);
|
||||
|
||||
// Start decoding
|
||||
int NumberValuesDecoded = 0;
|
||||
while (NumberValuesDecoded < NumberValues)
|
||||
int numberValuesDecoded = 0;
|
||||
while (numberValuesDecoded < numberValues)
|
||||
{
|
||||
switch (IntEncoded.GetEncoding())
|
||||
switch (intEncoded.GetEncoding())
|
||||
{
|
||||
case EIntegerEncoding.Quint:
|
||||
{
|
||||
DecodeQuintBlock(BitStream, DecodeIntegerSequence, IntEncoded.NumberBits);
|
||||
NumberValuesDecoded += 3;
|
||||
DecodeQuintBlock(bitStream, decodeIntegerSequence, intEncoded.NumberBits);
|
||||
numberValuesDecoded += 3;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EIntegerEncoding.Trit:
|
||||
{
|
||||
DecodeTritBlock(BitStream, DecodeIntegerSequence, IntEncoded.NumberBits);
|
||||
NumberValuesDecoded += 5;
|
||||
DecodeTritBlock(bitStream, decodeIntegerSequence, intEncoded.NumberBits);
|
||||
numberValuesDecoded += 5;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EIntegerEncoding.JustBits:
|
||||
{
|
||||
IntEncoded.BitValue = BitStream.ReadBits(IntEncoded.NumberBits);
|
||||
DecodeIntegerSequence.Add(IntEncoded);
|
||||
NumberValuesDecoded++;
|
||||
intEncoded.BitValue = bitStream.ReadBits(intEncoded.NumberBits);
|
||||
decodeIntegerSequence.Add(intEncoded);
|
||||
numberValuesDecoded++;
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -4,42 +4,42 @@ namespace Ryujinx.Graphics.Texture
|
|||
{
|
||||
class LinearSwizzle : ISwizzle
|
||||
{
|
||||
private int Pitch;
|
||||
private int Bpp;
|
||||
private int _pitch;
|
||||
private int _bpp;
|
||||
|
||||
private int SliceSize;
|
||||
private int _sliceSize;
|
||||
|
||||
public LinearSwizzle(int Pitch, int Bpp, int Width, int Height)
|
||||
public LinearSwizzle(int pitch, int bpp, int width, int height)
|
||||
{
|
||||
this.Pitch = Pitch;
|
||||
this.Bpp = Bpp;
|
||||
SliceSize = Width * Height * Bpp;
|
||||
this._pitch = pitch;
|
||||
this._bpp = bpp;
|
||||
_sliceSize = width * height * bpp;
|
||||
}
|
||||
|
||||
public void SetMipLevel(int Level)
|
||||
public void SetMipLevel(int level)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int GetMipOffset(int Level)
|
||||
public int GetMipOffset(int level)
|
||||
{
|
||||
if (Level == 1)
|
||||
return SliceSize;
|
||||
if (level == 1)
|
||||
return _sliceSize;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int GetImageSize(int MipsCount)
|
||||
public int GetImageSize(int mipsCount)
|
||||
{
|
||||
int Size = GetMipOffset(MipsCount);
|
||||
int size = GetMipOffset(mipsCount);
|
||||
|
||||
Size = (Size + 0x1fff) & ~0x1fff;
|
||||
size = (size + 0x1fff) & ~0x1fff;
|
||||
|
||||
return Size;
|
||||
return size;
|
||||
}
|
||||
|
||||
public int GetSwizzleOffset(int X, int Y, int Z)
|
||||
public int GetSwizzleOffset(int x, int y, int z)
|
||||
{
|
||||
return Z * SliceSize + X * Bpp + Y * Pitch;
|
||||
return z * _sliceSize + x * _bpp + y * _pitch;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,161 +6,161 @@ namespace Ryujinx.Graphics.Texture
|
|||
{
|
||||
static class TextureFactory
|
||||
{
|
||||
public static GalImage MakeTexture(NvGpuVmm Vmm, long TicPosition)
|
||||
public static GalImage MakeTexture(NvGpuVmm vmm, long ticPosition)
|
||||
{
|
||||
int[] Tic = ReadWords(Vmm, TicPosition, 8);
|
||||
int[] tic = ReadWords(vmm, ticPosition, 8);
|
||||
|
||||
GalImageFormat Format = GetImageFormat(Tic);
|
||||
GalImageFormat format = GetImageFormat(tic);
|
||||
|
||||
GalTextureTarget TextureTarget = (GalTextureTarget)((Tic[4] >> 23) & 0xF);
|
||||
GalTextureTarget textureTarget = (GalTextureTarget)((tic[4] >> 23) & 0xF);
|
||||
|
||||
GalTextureSource XSource = (GalTextureSource)((Tic[0] >> 19) & 7);
|
||||
GalTextureSource YSource = (GalTextureSource)((Tic[0] >> 22) & 7);
|
||||
GalTextureSource ZSource = (GalTextureSource)((Tic[0] >> 25) & 7);
|
||||
GalTextureSource WSource = (GalTextureSource)((Tic[0] >> 28) & 7);
|
||||
GalTextureSource xSource = (GalTextureSource)((tic[0] >> 19) & 7);
|
||||
GalTextureSource ySource = (GalTextureSource)((tic[0] >> 22) & 7);
|
||||
GalTextureSource zSource = (GalTextureSource)((tic[0] >> 25) & 7);
|
||||
GalTextureSource wSource = (GalTextureSource)((tic[0] >> 28) & 7);
|
||||
|
||||
TextureSwizzle Swizzle = (TextureSwizzle)((Tic[2] >> 21) & 7);
|
||||
TextureSwizzle swizzle = (TextureSwizzle)((tic[2] >> 21) & 7);
|
||||
|
||||
int MaxMipmapLevel = (Tic[3] >> 28) & 0xF + 1;
|
||||
int maxMipmapLevel = (tic[3] >> 28) & 0xF + 1;
|
||||
|
||||
GalMemoryLayout Layout;
|
||||
GalMemoryLayout layout;
|
||||
|
||||
if (Swizzle == TextureSwizzle.BlockLinear ||
|
||||
Swizzle == TextureSwizzle.BlockLinearColorKey)
|
||||
if (swizzle == TextureSwizzle.BlockLinear ||
|
||||
swizzle == TextureSwizzle.BlockLinearColorKey)
|
||||
{
|
||||
Layout = GalMemoryLayout.BlockLinear;
|
||||
layout = GalMemoryLayout.BlockLinear;
|
||||
}
|
||||
else
|
||||
{
|
||||
Layout = GalMemoryLayout.Pitch;
|
||||
layout = GalMemoryLayout.Pitch;
|
||||
}
|
||||
|
||||
int GobBlockHeightLog2 = (Tic[3] >> 3) & 7;
|
||||
int GobBlockDepthLog2 = (Tic[3] >> 6) & 7;
|
||||
int TileWidthLog2 = (Tic[3] >> 10) & 7;
|
||||
int gobBlockHeightLog2 = (tic[3] >> 3) & 7;
|
||||
int gobBlockDepthLog2 = (tic[3] >> 6) & 7;
|
||||
int tileWidthLog2 = (tic[3] >> 10) & 7;
|
||||
|
||||
int GobBlockHeight = 1 << GobBlockHeightLog2;
|
||||
int GobBlockDepth = 1 << GobBlockDepthLog2;
|
||||
int TileWidth = 1 << TileWidthLog2;
|
||||
int gobBlockHeight = 1 << gobBlockHeightLog2;
|
||||
int gobBlockDepth = 1 << gobBlockDepthLog2;
|
||||
int tileWidth = 1 << tileWidthLog2;
|
||||
|
||||
int Width = ((Tic[4] >> 0) & 0xffff) + 1;
|
||||
int Height = ((Tic[5] >> 0) & 0xffff) + 1;
|
||||
int Depth = ((Tic[5] >> 16) & 0x3fff) + 1;
|
||||
int width = ((tic[4] >> 0) & 0xffff) + 1;
|
||||
int height = ((tic[5] >> 0) & 0xffff) + 1;
|
||||
int depth = ((tic[5] >> 16) & 0x3fff) + 1;
|
||||
|
||||
int LayoutCount = 1;
|
||||
int layoutCount = 1;
|
||||
|
||||
// TODO: check this
|
||||
if (ImageUtils.IsArray(TextureTarget))
|
||||
if (ImageUtils.IsArray(textureTarget))
|
||||
{
|
||||
LayoutCount = Depth;
|
||||
Depth = 1;
|
||||
layoutCount = depth;
|
||||
depth = 1;
|
||||
}
|
||||
|
||||
if (TextureTarget == GalTextureTarget.OneD)
|
||||
if (textureTarget == GalTextureTarget.OneD)
|
||||
{
|
||||
Height = 1;
|
||||
height = 1;
|
||||
}
|
||||
|
||||
if (TextureTarget == GalTextureTarget.TwoD || TextureTarget == GalTextureTarget.OneD)
|
||||
if (textureTarget == GalTextureTarget.TwoD || textureTarget == GalTextureTarget.OneD)
|
||||
{
|
||||
Depth = 1;
|
||||
depth = 1;
|
||||
}
|
||||
else if (TextureTarget == GalTextureTarget.CubeMap)
|
||||
else if (textureTarget == GalTextureTarget.CubeMap)
|
||||
{
|
||||
// FIXME: This is a bit hacky but I guess it's fine for now
|
||||
LayoutCount = 6;
|
||||
Depth = 1;
|
||||
layoutCount = 6;
|
||||
depth = 1;
|
||||
}
|
||||
else if (TextureTarget == GalTextureTarget.CubeArray)
|
||||
else if (textureTarget == GalTextureTarget.CubeArray)
|
||||
{
|
||||
// FIXME: This is a really really hacky but I guess it's fine for now
|
||||
LayoutCount *= 6;
|
||||
Depth = 1;
|
||||
layoutCount *= 6;
|
||||
depth = 1;
|
||||
}
|
||||
|
||||
GalImage Image = new GalImage(
|
||||
Width,
|
||||
Height,
|
||||
Depth,
|
||||
LayoutCount,
|
||||
TileWidth,
|
||||
GobBlockHeight,
|
||||
GobBlockDepth,
|
||||
Layout,
|
||||
Format,
|
||||
TextureTarget,
|
||||
MaxMipmapLevel,
|
||||
XSource,
|
||||
YSource,
|
||||
ZSource,
|
||||
WSource);
|
||||
GalImage image = new GalImage(
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
layoutCount,
|
||||
tileWidth,
|
||||
gobBlockHeight,
|
||||
gobBlockDepth,
|
||||
layout,
|
||||
format,
|
||||
textureTarget,
|
||||
maxMipmapLevel,
|
||||
xSource,
|
||||
ySource,
|
||||
zSource,
|
||||
wSource);
|
||||
|
||||
if (Layout == GalMemoryLayout.Pitch)
|
||||
if (layout == GalMemoryLayout.Pitch)
|
||||
{
|
||||
Image.Pitch = (Tic[3] & 0xffff) << 5;
|
||||
image.Pitch = (tic[3] & 0xffff) << 5;
|
||||
}
|
||||
|
||||
return Image;
|
||||
return image;
|
||||
}
|
||||
|
||||
public static GalTextureSampler MakeSampler(NvGpu Gpu, NvGpuVmm Vmm, long TscPosition)
|
||||
public static GalTextureSampler MakeSampler(NvGpu gpu, NvGpuVmm vmm, long tscPosition)
|
||||
{
|
||||
int[] Tsc = ReadWords(Vmm, TscPosition, 8);
|
||||
int[] tsc = ReadWords(vmm, tscPosition, 8);
|
||||
|
||||
GalTextureWrap AddressU = (GalTextureWrap)((Tsc[0] >> 0) & 7);
|
||||
GalTextureWrap AddressV = (GalTextureWrap)((Tsc[0] >> 3) & 7);
|
||||
GalTextureWrap AddressP = (GalTextureWrap)((Tsc[0] >> 6) & 7);
|
||||
GalTextureWrap addressU = (GalTextureWrap)((tsc[0] >> 0) & 7);
|
||||
GalTextureWrap addressV = (GalTextureWrap)((tsc[0] >> 3) & 7);
|
||||
GalTextureWrap addressP = (GalTextureWrap)((tsc[0] >> 6) & 7);
|
||||
|
||||
bool DepthCompare = ((Tsc[0] >> 9) & 1) == 1;
|
||||
bool depthCompare = ((tsc[0] >> 9) & 1) == 1;
|
||||
|
||||
DepthCompareFunc DepthCompareFunc = (DepthCompareFunc)((Tsc[0] >> 10) & 7);
|
||||
DepthCompareFunc depthCompareFunc = (DepthCompareFunc)((tsc[0] >> 10) & 7);
|
||||
|
||||
GalTextureFilter MagFilter = (GalTextureFilter) ((Tsc[1] >> 0) & 3);
|
||||
GalTextureFilter MinFilter = (GalTextureFilter) ((Tsc[1] >> 4) & 3);
|
||||
GalTextureMipFilter MipFilter = (GalTextureMipFilter)((Tsc[1] >> 6) & 3);
|
||||
GalTextureFilter magFilter = (GalTextureFilter) ((tsc[1] >> 0) & 3);
|
||||
GalTextureFilter minFilter = (GalTextureFilter) ((tsc[1] >> 4) & 3);
|
||||
GalTextureMipFilter mipFilter = (GalTextureMipFilter)((tsc[1] >> 6) & 3);
|
||||
|
||||
GalColorF BorderColor = new GalColorF(
|
||||
BitConverter.Int32BitsToSingle(Tsc[4]),
|
||||
BitConverter.Int32BitsToSingle(Tsc[5]),
|
||||
BitConverter.Int32BitsToSingle(Tsc[6]),
|
||||
BitConverter.Int32BitsToSingle(Tsc[7]));
|
||||
GalColorF borderColor = new GalColorF(
|
||||
BitConverter.Int32BitsToSingle(tsc[4]),
|
||||
BitConverter.Int32BitsToSingle(tsc[5]),
|
||||
BitConverter.Int32BitsToSingle(tsc[6]),
|
||||
BitConverter.Int32BitsToSingle(tsc[7]));
|
||||
|
||||
return new GalTextureSampler(
|
||||
AddressU,
|
||||
AddressV,
|
||||
AddressP,
|
||||
MinFilter,
|
||||
MagFilter,
|
||||
MipFilter,
|
||||
BorderColor,
|
||||
DepthCompare,
|
||||
DepthCompareFunc);
|
||||
addressU,
|
||||
addressV,
|
||||
addressP,
|
||||
minFilter,
|
||||
magFilter,
|
||||
mipFilter,
|
||||
borderColor,
|
||||
depthCompare,
|
||||
depthCompareFunc);
|
||||
}
|
||||
|
||||
private static GalImageFormat GetImageFormat(int[] Tic)
|
||||
private static GalImageFormat GetImageFormat(int[] tic)
|
||||
{
|
||||
GalTextureType RType = (GalTextureType)((Tic[0] >> 7) & 7);
|
||||
GalTextureType GType = (GalTextureType)((Tic[0] >> 10) & 7);
|
||||
GalTextureType BType = (GalTextureType)((Tic[0] >> 13) & 7);
|
||||
GalTextureType AType = (GalTextureType)((Tic[0] >> 16) & 7);
|
||||
GalTextureType rType = (GalTextureType)((tic[0] >> 7) & 7);
|
||||
GalTextureType gType = (GalTextureType)((tic[0] >> 10) & 7);
|
||||
GalTextureType bType = (GalTextureType)((tic[0] >> 13) & 7);
|
||||
GalTextureType aType = (GalTextureType)((tic[0] >> 16) & 7);
|
||||
|
||||
GalTextureFormat Format = (GalTextureFormat)(Tic[0] & 0x7f);
|
||||
GalTextureFormat format = (GalTextureFormat)(tic[0] & 0x7f);
|
||||
|
||||
bool ConvSrgb = ((Tic[4] >> 22) & 1) != 0;
|
||||
bool convSrgb = ((tic[4] >> 22) & 1) != 0;
|
||||
|
||||
return ImageUtils.ConvertTexture(Format, RType, GType, BType, AType, ConvSrgb);
|
||||
return ImageUtils.ConvertTexture(format, rType, gType, bType, aType, convSrgb);
|
||||
}
|
||||
|
||||
private static int[] ReadWords(NvGpuVmm Vmm, long Position, int Count)
|
||||
private static int[] ReadWords(NvGpuVmm vmm, long position, int count)
|
||||
{
|
||||
int[] Words = new int[Count];
|
||||
int[] words = new int[count];
|
||||
|
||||
for (int Index = 0; Index < Count; Index++, Position += 4)
|
||||
for (int index = 0; index < count; index++, position += 4)
|
||||
{
|
||||
Words[Index] = Vmm.ReadInt32(Position);
|
||||
words[index] = vmm.ReadInt32(position);
|
||||
}
|
||||
|
||||
return Words;
|
||||
return words;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,47 +7,47 @@ namespace Ryujinx.Graphics.Texture
|
|||
{
|
||||
static class TextureHelper
|
||||
{
|
||||
public static ISwizzle GetSwizzle(GalImage Image)
|
||||
public static ISwizzle GetSwizzle(GalImage image)
|
||||
{
|
||||
int BlockWidth = ImageUtils.GetBlockWidth (Image.Format);
|
||||
int BlockHeight = ImageUtils.GetBlockHeight (Image.Format);
|
||||
int BlockDepth = ImageUtils.GetBlockDepth (Image.Format);
|
||||
int BytesPerPixel = ImageUtils.GetBytesPerPixel(Image.Format);
|
||||
int blockWidth = ImageUtils.GetBlockWidth (image.Format);
|
||||
int blockHeight = ImageUtils.GetBlockHeight (image.Format);
|
||||
int blockDepth = ImageUtils.GetBlockDepth (image.Format);
|
||||
int bytesPerPixel = ImageUtils.GetBytesPerPixel(image.Format);
|
||||
|
||||
int Width = BitUtils.DivRoundUp(Image.Width, BlockWidth);
|
||||
int Height = BitUtils.DivRoundUp(Image.Height, BlockHeight);
|
||||
int Depth = BitUtils.DivRoundUp(Image.Depth, BlockDepth);
|
||||
int width = BitUtils.DivRoundUp(image.Width, blockWidth);
|
||||
int height = BitUtils.DivRoundUp(image.Height, blockHeight);
|
||||
int depth = BitUtils.DivRoundUp(image.Depth, blockDepth);
|
||||
|
||||
if (Image.Layout == GalMemoryLayout.BlockLinear)
|
||||
if (image.Layout == GalMemoryLayout.BlockLinear)
|
||||
{
|
||||
int AlignMask = Image.TileWidth * (64 / BytesPerPixel) - 1;
|
||||
int alignMask = image.TileWidth * (64 / bytesPerPixel) - 1;
|
||||
|
||||
Width = (Width + AlignMask) & ~AlignMask;
|
||||
width = (width + alignMask) & ~alignMask;
|
||||
|
||||
return new BlockLinearSwizzle(
|
||||
Width,
|
||||
Height,
|
||||
Depth,
|
||||
Image.GobBlockHeight,
|
||||
Image.GobBlockDepth,
|
||||
BytesPerPixel);
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
image.GobBlockHeight,
|
||||
image.GobBlockDepth,
|
||||
bytesPerPixel);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new LinearSwizzle(Image.Pitch, BytesPerPixel, Width, Height);
|
||||
return new LinearSwizzle(image.Pitch, bytesPerPixel, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
public static (MemoryManager Memory, long Position) GetMemoryAndPosition(
|
||||
IMemory Memory,
|
||||
long Position)
|
||||
IMemory memory,
|
||||
long position)
|
||||
{
|
||||
if (Memory is NvGpuVmm Vmm)
|
||||
if (memory is NvGpuVmm vmm)
|
||||
{
|
||||
return (Vmm.Memory, Vmm.GetPhysicalAddress(Position));
|
||||
return (vmm.Memory, vmm.GetPhysicalAddress(position));
|
||||
}
|
||||
|
||||
return ((MemoryManager)Memory, Position);
|
||||
return ((MemoryManager)memory, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ namespace Ryujinx.Graphics.Texture
|
|||
{
|
||||
public enum TextureSwizzle
|
||||
{
|
||||
_1dBuffer = 0,
|
||||
_1DBuffer = 0,
|
||||
PitchColorKey = 1,
|
||||
Pitch = 2,
|
||||
BlockLinear = 3,
|
||||
|
|
Loading…
Add table
Reference in a new issue