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 textureBlockHeight = ImageUtils.GetBlockHeight(image.Format);
|
||||||
int textureBlockDepth = ImageUtils.GetBlockDepth(image.Format);
|
int textureBlockDepth = ImageUtils.GetBlockDepth(image.Format);
|
||||||
|
|
||||||
data = ASTCDecoder.DecodeToRGBA8888(
|
data = AstcDecoder.DecodeToRGBA8888(
|
||||||
data,
|
data,
|
||||||
textureBlockWidth,
|
textureBlockWidth,
|
||||||
textureBlockHeight,
|
textureBlockHeight,
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,24 +3,24 @@ using System.Diagnostics;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Texture
|
namespace Ryujinx.Graphics.Texture
|
||||||
{
|
{
|
||||||
class ASTCPixel
|
class AstcPixel
|
||||||
{
|
{
|
||||||
public short R { get; set; }
|
public short R { get; set; }
|
||||||
public short G { get; set; }
|
public short G { get; set; }
|
||||||
public short B { get; set; }
|
public short B { get; set; }
|
||||||
public short A { 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;
|
A = a;
|
||||||
R = _R;
|
R = r;
|
||||||
G = _G;
|
G = g;
|
||||||
B = _B;
|
B = b;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
BitDepth[i] = 8;
|
_bitDepth[i] = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClampByte()
|
public void ClampByte()
|
||||||
|
@ -31,9 +31,9 @@ namespace Ryujinx.Graphics.Texture
|
||||||
A = Math.Min(Math.Max(A, (short)0), (short)255);
|
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 0: return A;
|
||||||
case 1: return R;
|
case 1: return R;
|
||||||
|
@ -44,92 +44,92 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetComponent(int Index, int Value)
|
public void SetComponent(int index, int value)
|
||||||
{
|
{
|
||||||
switch (Index)
|
switch (index)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
A = (short)Value;
|
A = (short)value;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
R = (short)Value;
|
R = (short)value;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
G = (short)Value;
|
G = (short)value;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
B = (short)Value;
|
B = (short)value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeBitDepth(byte[] Depth)
|
public void ChangeBitDepth(byte[] depth)
|
||||||
{
|
{
|
||||||
for(int i = 0; i< 4; i++)
|
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);
|
SetComponent(i, value);
|
||||||
BitDepth[i] = Depth[i];
|
_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(newDepth <= 8);
|
||||||
Debug.Assert(OldDepth <= 8);
|
Debug.Assert(oldDepth <= 8);
|
||||||
|
|
||||||
if (OldDepth == NewDepth)
|
if (oldDepth == newDepth)
|
||||||
{
|
{
|
||||||
// Do nothing
|
// 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
|
else
|
||||||
{
|
{
|
||||||
// oldDepth > newDepth
|
// oldDepth > newDepth
|
||||||
if (NewDepth == 0)
|
if (newDepth == 0)
|
||||||
{
|
{
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
byte BitsWasted = (byte)(OldDepth - NewDepth);
|
byte bitsWasted = (byte)(oldDepth - newDepth);
|
||||||
short TempValue = Value;
|
short tempValue = value;
|
||||||
|
|
||||||
TempValue = (short)((TempValue + (1 << (BitsWasted - 1))) >> BitsWasted);
|
tempValue = (short)((tempValue + (1 << (bitsWasted - 1))) >> bitsWasted);
|
||||||
TempValue = Math.Min(Math.Max((short)0, TempValue), (short)((1 << NewDepth) - 1));
|
tempValue = Math.Min(Math.Max((short)0, tempValue), (short)((1 << newDepth) - 1));
|
||||||
|
|
||||||
return (byte)(TempValue);
|
return (byte)(tempValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Pack()
|
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 };
|
byte[] eightBitDepth = { 8, 8, 8, 8 };
|
||||||
|
|
||||||
NewPixel.ChangeBitDepth(eightBitDepth);
|
newPixel.ChangeBitDepth(eightBitDepth);
|
||||||
|
|
||||||
return (byte)NewPixel.A << 24 |
|
return (byte)newPixel.A << 24 |
|
||||||
(byte)NewPixel.B << 16 |
|
(byte)newPixel.B << 16 |
|
||||||
(byte)NewPixel.G << 8 |
|
(byte)newPixel.G << 8 |
|
||||||
(byte)NewPixel.R << 0;
|
(byte)newPixel.R << 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds more precision to the blue channel as described
|
// Adds more precision to the blue channel as described
|
||||||
// in C.2.14
|
// 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)((r + b) >> 1),
|
||||||
(short)((g + b) >> 1),
|
(short)((g + b) >> 1),
|
||||||
(short)(b));
|
(short)(b));
|
||||||
|
|
|
@ -9,103 +9,103 @@ namespace Ryujinx.Graphics.Texture
|
||||||
|
|
||||||
public int Position { get; private set; }
|
public int Position { get; private set; }
|
||||||
|
|
||||||
public BitArrayStream(BitArray BitArray)
|
public BitArrayStream(BitArray bitArray)
|
||||||
{
|
{
|
||||||
BitsArray = BitArray;
|
BitsArray = bitArray;
|
||||||
Position = 0;
|
Position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short ReadBits(int Length)
|
public short ReadBits(int length)
|
||||||
{
|
{
|
||||||
int RetValue = 0;
|
int retValue = 0;
|
||||||
for (int i = Position; i < Position + Length; i++)
|
for (int i = Position; i < Position + length; i++)
|
||||||
{
|
{
|
||||||
if (BitsArray[i])
|
if (BitsArray[i])
|
||||||
{
|
{
|
||||||
RetValue |= 1 << (i - Position);
|
retValue |= 1 << (i - Position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Position += Length;
|
Position += length;
|
||||||
return (short)RetValue;
|
return (short)retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ReadBits(int Start, int End)
|
public int ReadBits(int start, int end)
|
||||||
{
|
{
|
||||||
int RetValue = 0;
|
int retValue = 0;
|
||||||
for (int i = Start; i <= End; i++)
|
for (int i = start; i <= end; i++)
|
||||||
{
|
{
|
||||||
if (BitsArray[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()
|
public byte[] ToByteArray()
|
||||||
{
|
{
|
||||||
byte[] RetArray = new byte[(BitsArray.Length + 7) / 8];
|
byte[] retArray = new byte[(BitsArray.Length + 7) / 8];
|
||||||
BitsArray.CopyTo(RetArray, 0);
|
BitsArray.CopyTo(retArray, 0);
|
||||||
return RetArray;
|
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 (numberBits == 0) return 0;
|
||||||
if (ToBit == 0) return 0;
|
if (toBit == 0) return 0;
|
||||||
|
|
||||||
int TempValue = Value & ((1 << NumberBits) - 1);
|
int tempValue = value & ((1 << numberBits) - 1);
|
||||||
int RetValue = TempValue;
|
int retValue = tempValue;
|
||||||
int ResLength = NumberBits;
|
int resLength = numberBits;
|
||||||
|
|
||||||
while (ResLength < ToBit)
|
while (resLength < toBit)
|
||||||
{
|
{
|
||||||
int Comp = 0;
|
int comp = 0;
|
||||||
if (NumberBits > ToBit - ResLength)
|
if (numberBits > toBit - resLength)
|
||||||
{
|
{
|
||||||
int NewShift = ToBit - ResLength;
|
int newShift = toBit - resLength;
|
||||||
Comp = NumberBits - NewShift;
|
comp = numberBits - newShift;
|
||||||
NumberBits = NewShift;
|
numberBits = newShift;
|
||||||
}
|
}
|
||||||
RetValue <<= NumberBits;
|
retValue <<= numberBits;
|
||||||
RetValue |= TempValue >> Comp;
|
retValue |= tempValue >> comp;
|
||||||
ResLength += NumberBits;
|
resLength += numberBits;
|
||||||
}
|
}
|
||||||
return RetValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int PopCnt(int Number)
|
public static int PopCnt(int number)
|
||||||
{
|
{
|
||||||
int Counter;
|
int counter;
|
||||||
for (Counter = 0; Number != 0; 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)
|
public static void Swap<T>(ref T lhs, ref T rhs)
|
||||||
{
|
{
|
||||||
T Temp = lhs;
|
T temp = lhs;
|
||||||
lhs = rhs;
|
lhs = rhs;
|
||||||
rhs = Temp;
|
rhs = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transfers a bit as described in C.2.14
|
// Transfers a bit as described in C.2.14
|
||||||
|
|
|
@ -10,98 +10,98 @@ namespace Ryujinx.Graphics.Texture
|
||||||
|
|
||||||
private const int GobSize = GobWidth * GobHeight;
|
private const int GobSize = GobWidth * GobHeight;
|
||||||
|
|
||||||
private int TexWidth;
|
private int _texWidth;
|
||||||
private int TexHeight;
|
private int _texHeight;
|
||||||
private int TexDepth;
|
private int _texDepth;
|
||||||
private int TexGobBlockHeight;
|
private int _texGobBlockHeight;
|
||||||
private int TexGobBlockDepth;
|
private int _texGobBlockDepth;
|
||||||
private int TexBpp;
|
private int _texBpp;
|
||||||
|
|
||||||
private int BhMask;
|
private int _bhMask;
|
||||||
private int BdMask;
|
private int _bdMask;
|
||||||
|
|
||||||
private int BhShift;
|
private int _bhShift;
|
||||||
private int BdShift;
|
private int _bdShift;
|
||||||
private int BppShift;
|
private int _bppShift;
|
||||||
|
|
||||||
private int XShift;
|
private int _xShift;
|
||||||
|
|
||||||
private int RobSize;
|
private int _robSize;
|
||||||
private int SliceSize;
|
private int _sliceSize;
|
||||||
|
|
||||||
private int BaseOffset;
|
private int _baseOffset;
|
||||||
|
|
||||||
public BlockLinearSwizzle(
|
public BlockLinearSwizzle(
|
||||||
int Width,
|
int width,
|
||||||
int Height,
|
int height,
|
||||||
int Depth,
|
int depth,
|
||||||
int GobBlockHeight,
|
int gobBlockHeight,
|
||||||
int GobBlockDepth,
|
int gobBlockDepth,
|
||||||
int Bpp)
|
int bpp)
|
||||||
{
|
{
|
||||||
TexWidth = Width;
|
_texWidth = width;
|
||||||
TexHeight = Height;
|
_texHeight = height;
|
||||||
TexDepth = Depth;
|
_texDepth = depth;
|
||||||
TexGobBlockHeight = GobBlockHeight;
|
_texGobBlockHeight = gobBlockHeight;
|
||||||
TexGobBlockDepth = GobBlockDepth;
|
_texGobBlockDepth = gobBlockDepth;
|
||||||
TexBpp = Bpp;
|
_texBpp = bpp;
|
||||||
|
|
||||||
BppShift = BitUtils.CountTrailingZeros32(Bpp);
|
_bppShift = BitUtils.CountTrailingZeros32(bpp);
|
||||||
|
|
||||||
SetMipLevel(0);
|
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 width = Math.Max(1, _texWidth >> level);
|
||||||
int Height = Math.Max(1, TexHeight >> Level);
|
int height = Math.Max(1, _texHeight >> level);
|
||||||
int Depth = Math.Max(1, TexDepth >> Level);
|
int depth = Math.Max(1, _texDepth >> level);
|
||||||
|
|
||||||
GobBlockSizes GbSizes = AdjustGobBlockSizes(Height, Depth);
|
GobBlockSizes gbSizes = AdjustGobBlockSizes(height, depth);
|
||||||
|
|
||||||
BhMask = GbSizes.Height - 1;
|
_bhMask = gbSizes.Height - 1;
|
||||||
BdMask = GbSizes.Depth - 1;
|
_bdMask = gbSizes.Depth - 1;
|
||||||
|
|
||||||
BhShift = BitUtils.CountTrailingZeros32(GbSizes.Height);
|
_bhShift = BitUtils.CountTrailingZeros32(gbSizes.Height);
|
||||||
BdShift = BitUtils.CountTrailingZeros32(GbSizes.Depth);
|
_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;
|
_robSize = gsSizes.RobSize;
|
||||||
SliceSize = GsSizes.SliceSize;
|
_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 width = Math.Max(1, _texWidth >> index);
|
||||||
int Height = Math.Max(1, TexHeight >> Index);
|
int height = Math.Max(1, _texHeight >> index);
|
||||||
int Depth = Math.Max(1, TexDepth >> 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
|
private struct GobBlockSizes
|
||||||
|
@ -109,32 +109,32 @@ namespace Ryujinx.Graphics.Texture
|
||||||
public int Height;
|
public int Height;
|
||||||
public int Depth;
|
public int Depth;
|
||||||
|
|
||||||
public GobBlockSizes(int GobBlockHeight, int GobBlockDepth)
|
public GobBlockSizes(int gobBlockHeight, int gobBlockDepth)
|
||||||
{
|
{
|
||||||
this.Height = GobBlockHeight;
|
this.Height = gobBlockHeight;
|
||||||
this.Depth = GobBlockDepth;
|
this.Depth = gobBlockDepth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private GobBlockSizes AdjustGobBlockSizes(int Height, int Depth)
|
private GobBlockSizes AdjustGobBlockSizes(int height, int depth)
|
||||||
{
|
{
|
||||||
int GobBlockHeight = TexGobBlockHeight;
|
int gobBlockHeight = _texGobBlockHeight;
|
||||||
int GobBlockDepth = TexGobBlockDepth;
|
int gobBlockDepth = _texGobBlockDepth;
|
||||||
|
|
||||||
int Pow2Height = BitUtils.Pow2RoundUp(Height);
|
int pow2Height = BitUtils.Pow2RoundUp(height);
|
||||||
int Pow2Depth = BitUtils.Pow2RoundUp(Depth);
|
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
|
private struct RobAndSliceSizes
|
||||||
|
@ -142,45 +142,45 @@ namespace Ryujinx.Graphics.Texture
|
||||||
public int RobSize;
|
public int RobSize;
|
||||||
public int SliceSize;
|
public int SliceSize;
|
||||||
|
|
||||||
public RobAndSliceSizes(int RobSize, int SliceSize)
|
public RobAndSliceSizes(int robSize, int sliceSize)
|
||||||
{
|
{
|
||||||
this.RobSize = RobSize;
|
this.RobSize = robSize;
|
||||||
this.SliceSize = SliceSize;
|
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 += ((x & 0x3f) >> 5) << 8;
|
||||||
Position += ((Y & 0x07) >> 1) << 6;
|
position += ((y & 0x07) >> 1) << 6;
|
||||||
Position += ((X & 0x1f) >> 4) << 5;
|
position += ((x & 0x1f) >> 4) << 5;
|
||||||
Position += ((Y & 0x01) >> 0) << 4;
|
position += ((y & 0x01) >> 0) << 4;
|
||||||
Position += ((X & 0x0f) >> 0) << 0;
|
position += ((x & 0x0f) >> 0) << 0;
|
||||||
|
|
||||||
return BaseOffset + Position;
|
return _baseOffset + position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,12 +2,12 @@ namespace Ryujinx.Graphics.Texture
|
||||||
{
|
{
|
||||||
interface ISwizzle
|
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 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.BytesPerPixel = bytesPerPixel;
|
||||||
this.BlockWidth = BlockWidth;
|
this.BlockWidth = blockWidth;
|
||||||
this.BlockHeight = BlockHeight;
|
this.BlockHeight = blockHeight;
|
||||||
this.BlockDepth = BlockDepth;
|
this.BlockDepth = blockDepth;
|
||||||
this.Target = Target;
|
this.Target = target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
private const GalImageFormat Float = GalImageFormat.Float;
|
private const GalImageFormat Float = GalImageFormat.Float;
|
||||||
private const GalImageFormat Srgb = GalImageFormat.Srgb;
|
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>()
|
new Dictionary<GalTextureFormat, GalImageFormat>()
|
||||||
{
|
{
|
||||||
{ GalTextureFormat.RGBA32, GalImageFormat.RGBA32 | Sint | Uint | Float },
|
{ GalTextureFormat.RGBA32, GalImageFormat.RGBA32 | Sint | Uint | Float },
|
||||||
|
@ -93,7 +93,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
{ GalTextureFormat.Astc2D10x6, GalImageFormat.Astc2D10x6 | Unorm | Srgb }
|
{ 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>()
|
new Dictionary<GalImageFormat, ImageDescriptor>()
|
||||||
{
|
{
|
||||||
{ GalImageFormat.RGBA32, new ImageDescriptor(16, 1, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.RGBA32, new ImageDescriptor(16, 1, 1, 1, TargetBuffer.Color) },
|
||||||
|
@ -145,38 +145,38 @@ namespace Ryujinx.Graphics.Texture
|
||||||
};
|
};
|
||||||
|
|
||||||
public static GalImageFormat ConvertTexture(
|
public static GalImageFormat ConvertTexture(
|
||||||
GalTextureFormat Format,
|
GalTextureFormat format,
|
||||||
GalTextureType RType,
|
GalTextureType rType,
|
||||||
GalTextureType GType,
|
GalTextureType gType,
|
||||||
GalTextureType BType,
|
GalTextureType bType,
|
||||||
GalTextureType AType,
|
GalTextureType aType,
|
||||||
bool ConvSrgb)
|
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!");
|
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.RGBA32Float: return GalImageFormat.RGBA32 | Float;
|
||||||
case GalSurfaceFormat.RGBA32Uint: return GalImageFormat.RGBA32 | Uint;
|
case GalSurfaceFormat.RGBA32Uint: return GalImageFormat.RGBA32 | Uint;
|
||||||
|
@ -210,12 +210,12 @@ namespace Ryujinx.Graphics.Texture
|
||||||
case GalSurfaceFormat.RGBX8Unorm: return GalImageFormat.RGBX8 | Unorm;
|
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.D32Float: return GalImageFormat.D32 | Float;
|
||||||
case GalZetaFormat.S8D24Unorm: return GalImageFormat.D24S8 | Unorm;
|
case GalZetaFormat.S8D24Unorm: return GalImageFormat.D24S8 | Unorm;
|
||||||
|
@ -225,268 +225,268 @@ namespace Ryujinx.Graphics.Texture
|
||||||
case GalZetaFormat.D32S8X24Float: return GalImageFormat.D32S8 | Float;
|
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
|
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.
|
//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;
|
int dataLayerSize = height * pitch * depth;
|
||||||
byte[] Data = new byte[DataLayerSize * Image.LayerCount];
|
byte[] data = new byte[dataLayerSize * image.LayerCount];
|
||||||
|
|
||||||
int TargetMipLevel = Image.MaxMipmapLevel <= 1 ? 1 : Image.MaxMipmapLevel - 1;
|
int targetMipLevel = image.MaxMipmapLevel <= 1 ? 1 : image.MaxMipmapLevel - 1;
|
||||||
int LayerOffset = ImageUtils.GetLayerOffset(Image, TargetMipLevel);
|
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 z = 0; z < depth; z++)
|
||||||
for (int Y = 0; Y < Height; Y++)
|
for (int y = 0; y < height; y++)
|
||||||
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);
|
||||||
|
|
||||||
Vmm.Memory.WriteBytes(Position + Offset, Data, InOffs, BytesPerPixel);
|
vmm.Memory.WriteBytes(position + offset, data, inOffs, bytesPerPixel);
|
||||||
|
|
||||||
InOffs += BytesPerPixel;
|
inOffs += bytesPerPixel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Support non 2D
|
// TODO: Support non 2D
|
||||||
public static bool CopyTexture(
|
public static bool CopyTexture(
|
||||||
NvGpuVmm Vmm,
|
NvGpuVmm vmm,
|
||||||
GalImage SrcImage,
|
GalImage srcImage,
|
||||||
GalImage DstImage,
|
GalImage dstImage,
|
||||||
long SrcAddress,
|
long srcAddress,
|
||||||
long DstAddress,
|
long dstAddress,
|
||||||
int SrcX,
|
int srcX,
|
||||||
int SrcY,
|
int srcY,
|
||||||
int DstX,
|
int dstX,
|
||||||
int DstY,
|
int dstY,
|
||||||
int Width,
|
int width,
|
||||||
int Height)
|
int height)
|
||||||
{
|
{
|
||||||
ISwizzle SrcSwizzle = TextureHelper.GetSwizzle(SrcImage);
|
ISwizzle srcSwizzle = TextureHelper.GetSwizzle(srcImage);
|
||||||
ISwizzle DstSwizzle = TextureHelper.GetSwizzle(DstImage);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BytesPerPixel = Desc.BytesPerPixel;
|
int bytesPerPixel = desc.BytesPerPixel;
|
||||||
|
|
||||||
for (int Y = 0; Y < Height; Y++)
|
for (int y = 0; y < height; y++)
|
||||||
for (int X = 0; X < Width; X++)
|
for (int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
long SrcOffset = (uint)SrcSwizzle.GetSwizzleOffset(SrcX + X, SrcY + Y, 0);
|
long srcOffset = (uint)srcSwizzle.GetSwizzleOffset(srcX + x, srcY + y, 0);
|
||||||
long DstOffset = (uint)DstSwizzle.GetSwizzleOffset(DstX + X, DstY + 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;
|
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))
|
if (IsArray(image.TextureTarget))
|
||||||
ComponentCount--;
|
componentCount--;
|
||||||
|
|
||||||
int Width = DivRoundUp(Image.Width, Desc.BlockWidth);
|
int width = DivRoundUp(image.Width, desc.BlockWidth);
|
||||||
int Height = DivRoundUp(Image.Height, Desc.BlockHeight);
|
int height = DivRoundUp(image.Height, desc.BlockHeight);
|
||||||
int Depth = DivRoundUp(Image.Depth, Desc.BlockDepth);
|
int depth = DivRoundUp(image.Depth, desc.BlockDepth);
|
||||||
|
|
||||||
switch (ComponentCount)
|
switch (componentCount)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
return Desc.BytesPerPixel * Width * Image.LayerCount;
|
return desc.BytesPerPixel * width * image.LayerCount;
|
||||||
case 2:
|
case 2:
|
||||||
return Desc.BytesPerPixel * Width * Height * Image.LayerCount;
|
return desc.BytesPerPixel * width * height * image.LayerCount;
|
||||||
case 3:
|
case 3:
|
||||||
return Desc.BytesPerPixel * Width * Height * Depth * Image.LayerCount;
|
return desc.BytesPerPixel * width * height * depth * image.LayerCount;
|
||||||
default:
|
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
|
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),
|
return (DivRoundUp(image.Width, desc.BlockWidth),
|
||||||
DivRoundUp(Image.Height, Desc.BlockHeight),
|
DivRoundUp(image.Height, desc.BlockHeight),
|
||||||
DivRoundUp(Image.Depth, Desc.BlockDepth));
|
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.Snorm: return Snorm;
|
||||||
case GalTextureType.Unorm: return Unorm;
|
case GalTextureType.Unorm: return Unorm;
|
||||||
|
@ -494,13 +494,13 @@ namespace Ryujinx.Graphics.Texture
|
||||||
case GalTextureType.Uint: return Uint;
|
case GalTextureType.Uint: return Uint;
|
||||||
case GalTextureType.Float: return Float;
|
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:
|
case GalTextureTarget.OneD:
|
||||||
return TextureTarget.Texture1D;
|
return TextureTarget.Texture1D;
|
||||||
|
@ -520,13 +520,13 @@ namespace Ryujinx.Graphics.Texture
|
||||||
case GalTextureTarget.CubeArray:
|
case GalTextureTarget.CubeArray:
|
||||||
return TextureTarget.TextureCubeMapArray;
|
return TextureTarget.TextureCubeMapArray;
|
||||||
default:
|
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.OneDArray:
|
||||||
case GalTextureTarget.TwoDArray:
|
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:
|
case GalTextureTarget.OneD:
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -555,7 +555,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
case GalTextureTarget.CubeArray:
|
case GalTextureTarget.CubeArray:
|
||||||
return 4;
|
return 4;
|
||||||
default:
|
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
|
Trit
|
||||||
}
|
}
|
||||||
|
|
||||||
EIntegerEncoding Encoding;
|
EIntegerEncoding _encoding;
|
||||||
public int NumberBits { get; private set; }
|
public int NumberBits { get; private set; }
|
||||||
public int BitValue { get; private set; }
|
public int BitValue { get; private set; }
|
||||||
public int TritValue { get; private set; }
|
public int TritValue { get; private set; }
|
||||||
public int QuintValue { get; private set; }
|
public int QuintValue { get; private set; }
|
||||||
|
|
||||||
public IntegerEncoded(EIntegerEncoding _Encoding, int NumBits)
|
public IntegerEncoded(EIntegerEncoding encoding, int numBits)
|
||||||
{
|
{
|
||||||
Encoding = _Encoding;
|
_encoding = encoding;
|
||||||
NumberBits = NumBits;
|
NumberBits = numBits;
|
||||||
BitValue = 0;
|
BitValue = 0;
|
||||||
TritValue = 0;
|
TritValue = 0;
|
||||||
QuintValue = 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()
|
public EIntegerEncoding GetEncoding()
|
||||||
{
|
{
|
||||||
return Encoding;
|
return _encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetBitLength(int NumberVals)
|
public int GetBitLength(int numberVals)
|
||||||
{
|
{
|
||||||
int TotalBits = NumberBits * NumberVals;
|
int totalBits = NumberBits * numberVals;
|
||||||
if (Encoding == EIntegerEncoding.Trit)
|
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?
|
// 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?
|
// 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?
|
// 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...
|
// Apparently it can't be represented with a bounded integer sequence...
|
||||||
// just iterate.
|
// just iterate.
|
||||||
MaxVal--;
|
maxVal--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new IntegerEncoded(EIntegerEncoding.JustBits, 0);
|
return new IntegerEncoded(EIntegerEncoding.JustBits, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DecodeTritBlock(
|
public static void DecodeTritBlock(
|
||||||
BitArrayStream BitStream,
|
BitArrayStream bitStream,
|
||||||
List<IntegerEncoded> ListIntegerEncoded,
|
List<IntegerEncoded> listIntegerEncoded,
|
||||||
int NumberBitsPerValue)
|
int numberBitsPerValue)
|
||||||
{
|
{
|
||||||
// Implement the algorithm in section C.2.12
|
// Implement the algorithm in section C.2.12
|
||||||
int[] m = new int[5];
|
int[] m = new int[5];
|
||||||
|
@ -95,170 +95,170 @@ namespace Ryujinx.Graphics.Texture
|
||||||
|
|
||||||
// Read the trit encoded block according to
|
// Read the trit encoded block according to
|
||||||
// table C.2.14
|
// table C.2.14
|
||||||
m[0] = BitStream.ReadBits(NumberBitsPerValue);
|
m[0] = bitStream.ReadBits(numberBitsPerValue);
|
||||||
T = BitStream.ReadBits(2);
|
T = bitStream.ReadBits(2);
|
||||||
m[1] = BitStream.ReadBits(NumberBitsPerValue);
|
m[1] = bitStream.ReadBits(numberBitsPerValue);
|
||||||
T |= BitStream.ReadBits(2) << 2;
|
T |= bitStream.ReadBits(2) << 2;
|
||||||
m[2] = BitStream.ReadBits(NumberBitsPerValue);
|
m[2] = bitStream.ReadBits(numberBitsPerValue);
|
||||||
T |= BitStream.ReadBits(1) << 4;
|
T |= bitStream.ReadBits(1) << 4;
|
||||||
m[3] = BitStream.ReadBits(NumberBitsPerValue);
|
m[3] = bitStream.ReadBits(numberBitsPerValue);
|
||||||
T |= BitStream.ReadBits(2) << 5;
|
T |= bitStream.ReadBits(2) << 5;
|
||||||
m[4] = BitStream.ReadBits(NumberBitsPerValue);
|
m[4] = bitStream.ReadBits(numberBitsPerValue);
|
||||||
T |= BitStream.ReadBits(1) << 7;
|
T |= bitStream.ReadBits(1) << 7;
|
||||||
|
|
||||||
int C = 0;
|
int c = 0;
|
||||||
|
|
||||||
BitArrayStream Tb = new BitArrayStream(new BitArray(new int[] { T }));
|
BitArrayStream tb = new BitArrayStream(new BitArray(new int[] { T }));
|
||||||
if (Tb.ReadBits(2, 4) == 7)
|
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;
|
t[4] = t[3] = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
C = Tb.ReadBits(0, 4);
|
c = tb.ReadBits(0, 4);
|
||||||
if (Tb.ReadBits(5, 6) == 3)
|
if (tb.ReadBits(5, 6) == 3)
|
||||||
{
|
{
|
||||||
t[4] = 2;
|
t[4] = 2;
|
||||||
t[3] = Tb.ReadBit(7);
|
t[3] = tb.ReadBit(7);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
t[4] = Tb.ReadBit(7);
|
t[4] = tb.ReadBit(7);
|
||||||
t[3] = Tb.ReadBits(5, 6);
|
t[3] = tb.ReadBits(5, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BitArrayStream Cb = new BitArrayStream(new BitArray(new int[] { C }));
|
BitArrayStream cb = new BitArrayStream(new BitArray(new int[] { c }));
|
||||||
if (Cb.ReadBits(0, 1) == 3)
|
if (cb.ReadBits(0, 1) == 3)
|
||||||
{
|
{
|
||||||
t[2] = 2;
|
t[2] = 2;
|
||||||
t[1] = Cb.ReadBit(4);
|
t[1] = cb.ReadBit(4);
|
||||||
t[0] = (Cb.ReadBit(3) << 1) | (Cb.ReadBit(2) & ~Cb.ReadBit(3));
|
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[2] = 2;
|
||||||
t[1] = 2;
|
t[1] = 2;
|
||||||
t[0] = Cb.ReadBits(0, 1);
|
t[0] = cb.ReadBits(0, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
t[2] = Cb.ReadBit(4);
|
t[2] = cb.ReadBit(4);
|
||||||
t[1] = Cb.ReadBits(2, 3);
|
t[1] = cb.ReadBits(2, 3);
|
||||||
t[0] = (Cb.ReadBit(1) << 1) | (Cb.ReadBit(0) & ~Cb.ReadBit(1));
|
t[0] = (cb.ReadBit(1) << 1) | (cb.ReadBit(0) & ~cb.ReadBit(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
IntegerEncoded IntEncoded = new IntegerEncoded(EIntegerEncoding.Trit, NumberBitsPerValue)
|
IntegerEncoded intEncoded = new IntegerEncoded(EIntegerEncoding.Trit, numberBitsPerValue)
|
||||||
{
|
{
|
||||||
BitValue = m[i],
|
BitValue = m[i],
|
||||||
TritValue = t[i]
|
TritValue = t[i]
|
||||||
};
|
};
|
||||||
ListIntegerEncoded.Add(IntEncoded);
|
listIntegerEncoded.Add(intEncoded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DecodeQuintBlock(
|
public static void DecodeQuintBlock(
|
||||||
BitArrayStream BitStream,
|
BitArrayStream bitStream,
|
||||||
List<IntegerEncoded> ListIntegerEncoded,
|
List<IntegerEncoded> listIntegerEncoded,
|
||||||
int NumberBitsPerValue)
|
int numberBitsPerValue)
|
||||||
{
|
{
|
||||||
// Implement the algorithm in section C.2.12
|
// Implement the algorithm in section C.2.12
|
||||||
int[] m = new int[3];
|
int[] m = new int[3];
|
||||||
int[] qa = new int[3];
|
int[] qa = new int[3];
|
||||||
int Q;
|
int q;
|
||||||
|
|
||||||
// Read the trit encoded block according to
|
// Read the trit encoded block according to
|
||||||
// table C.2.15
|
// table C.2.15
|
||||||
m[0] = BitStream.ReadBits(NumberBitsPerValue);
|
m[0] = bitStream.ReadBits(numberBitsPerValue);
|
||||||
Q = BitStream.ReadBits(3);
|
q = bitStream.ReadBits(3);
|
||||||
m[1] = BitStream.ReadBits(NumberBitsPerValue);
|
m[1] = bitStream.ReadBits(numberBitsPerValue);
|
||||||
Q |= BitStream.ReadBits(2) << 3;
|
q |= bitStream.ReadBits(2) << 3;
|
||||||
m[2] = BitStream.ReadBits(NumberBitsPerValue);
|
m[2] = bitStream.ReadBits(numberBitsPerValue);
|
||||||
Q |= BitStream.ReadBits(2) << 5;
|
q |= bitStream.ReadBits(2) << 5;
|
||||||
|
|
||||||
BitArrayStream Qb = new BitArrayStream(new BitArray(new int[] { Q }));
|
BitArrayStream qb = new BitArrayStream(new BitArray(new int[] { q }));
|
||||||
if (Qb.ReadBits(1, 2) == 3 && Qb.ReadBits(5, 6) == 0)
|
if (qb.ReadBits(1, 2) == 3 && qb.ReadBits(5, 6) == 0)
|
||||||
{
|
{
|
||||||
qa[0] = qa[1] = 4;
|
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
|
else
|
||||||
{
|
{
|
||||||
int C = 0;
|
int c = 0;
|
||||||
if (Qb.ReadBits(1, 2) == 3)
|
if (qb.ReadBits(1, 2) == 3)
|
||||||
{
|
{
|
||||||
qa[2] = 4;
|
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
|
else
|
||||||
{
|
{
|
||||||
qa[2] = Qb.ReadBits(5, 6);
|
qa[2] = qb.ReadBits(5, 6);
|
||||||
C = Qb.ReadBits(0, 4);
|
c = qb.ReadBits(0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
BitArrayStream Cb = new BitArrayStream(new BitArray(new int[] { C }));
|
BitArrayStream cb = new BitArrayStream(new BitArray(new int[] { c }));
|
||||||
if (Cb.ReadBits(0, 2) == 5)
|
if (cb.ReadBits(0, 2) == 5)
|
||||||
{
|
{
|
||||||
qa[1] = 4;
|
qa[1] = 4;
|
||||||
qa[0] = Cb.ReadBits(3, 4);
|
qa[0] = cb.ReadBits(3, 4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qa[1] = Cb.ReadBits(3, 4);
|
qa[1] = cb.ReadBits(3, 4);
|
||||||
qa[0] = Cb.ReadBits(0, 2);
|
qa[0] = cb.ReadBits(0, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
IntegerEncoded IntEncoded = new IntegerEncoded(EIntegerEncoding.Quint, NumberBitsPerValue)
|
IntegerEncoded intEncoded = new IntegerEncoded(EIntegerEncoding.Quint, numberBitsPerValue)
|
||||||
{
|
{
|
||||||
BitValue = m[i],
|
BitValue = m[i],
|
||||||
QuintValue = qa[i]
|
QuintValue = qa[i]
|
||||||
};
|
};
|
||||||
ListIntegerEncoded.Add(IntEncoded);
|
listIntegerEncoded.Add(intEncoded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DecodeIntegerSequence(
|
public static void DecodeIntegerSequence(
|
||||||
List<IntegerEncoded> DecodeIntegerSequence,
|
List<IntegerEncoded> decodeIntegerSequence,
|
||||||
BitArrayStream BitStream,
|
BitArrayStream bitStream,
|
||||||
int MaxRange,
|
int maxRange,
|
||||||
int NumberValues)
|
int numberValues)
|
||||||
{
|
{
|
||||||
// Determine encoding parameters
|
// Determine encoding parameters
|
||||||
IntegerEncoded IntEncoded = CreateEncoding(MaxRange);
|
IntegerEncoded intEncoded = CreateEncoding(maxRange);
|
||||||
|
|
||||||
// Start decoding
|
// Start decoding
|
||||||
int NumberValuesDecoded = 0;
|
int numberValuesDecoded = 0;
|
||||||
while (NumberValuesDecoded < NumberValues)
|
while (numberValuesDecoded < numberValues)
|
||||||
{
|
{
|
||||||
switch (IntEncoded.GetEncoding())
|
switch (intEncoded.GetEncoding())
|
||||||
{
|
{
|
||||||
case EIntegerEncoding.Quint:
|
case EIntegerEncoding.Quint:
|
||||||
{
|
{
|
||||||
DecodeQuintBlock(BitStream, DecodeIntegerSequence, IntEncoded.NumberBits);
|
DecodeQuintBlock(bitStream, decodeIntegerSequence, intEncoded.NumberBits);
|
||||||
NumberValuesDecoded += 3;
|
numberValuesDecoded += 3;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EIntegerEncoding.Trit:
|
case EIntegerEncoding.Trit:
|
||||||
{
|
{
|
||||||
DecodeTritBlock(BitStream, DecodeIntegerSequence, IntEncoded.NumberBits);
|
DecodeTritBlock(bitStream, decodeIntegerSequence, intEncoded.NumberBits);
|
||||||
NumberValuesDecoded += 5;
|
numberValuesDecoded += 5;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EIntegerEncoding.JustBits:
|
case EIntegerEncoding.JustBits:
|
||||||
{
|
{
|
||||||
IntEncoded.BitValue = BitStream.ReadBits(IntEncoded.NumberBits);
|
intEncoded.BitValue = bitStream.ReadBits(intEncoded.NumberBits);
|
||||||
DecodeIntegerSequence.Add(IntEncoded);
|
decodeIntegerSequence.Add(intEncoded);
|
||||||
NumberValuesDecoded++;
|
numberValuesDecoded++;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,42 +4,42 @@ namespace Ryujinx.Graphics.Texture
|
||||||
{
|
{
|
||||||
class LinearSwizzle : ISwizzle
|
class LinearSwizzle : ISwizzle
|
||||||
{
|
{
|
||||||
private int Pitch;
|
private int _pitch;
|
||||||
private int Bpp;
|
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._pitch = pitch;
|
||||||
this.Bpp = Bpp;
|
this._bpp = bpp;
|
||||||
SliceSize = Width * Height * Bpp;
|
_sliceSize = width * height * bpp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetMipLevel(int Level)
|
public void SetMipLevel(int level)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetMipOffset(int Level)
|
public int GetMipOffset(int level)
|
||||||
{
|
{
|
||||||
if (Level == 1)
|
if (level == 1)
|
||||||
return SliceSize;
|
return _sliceSize;
|
||||||
throw new NotImplementedException();
|
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
|
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 xSource = (GalTextureSource)((tic[0] >> 19) & 7);
|
||||||
GalTextureSource YSource = (GalTextureSource)((Tic[0] >> 22) & 7);
|
GalTextureSource ySource = (GalTextureSource)((tic[0] >> 22) & 7);
|
||||||
GalTextureSource ZSource = (GalTextureSource)((Tic[0] >> 25) & 7);
|
GalTextureSource zSource = (GalTextureSource)((tic[0] >> 25) & 7);
|
||||||
GalTextureSource WSource = (GalTextureSource)((Tic[0] >> 28) & 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 ||
|
if (swizzle == TextureSwizzle.BlockLinear ||
|
||||||
Swizzle == TextureSwizzle.BlockLinearColorKey)
|
swizzle == TextureSwizzle.BlockLinearColorKey)
|
||||||
{
|
{
|
||||||
Layout = GalMemoryLayout.BlockLinear;
|
layout = GalMemoryLayout.BlockLinear;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Layout = GalMemoryLayout.Pitch;
|
layout = GalMemoryLayout.Pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GobBlockHeightLog2 = (Tic[3] >> 3) & 7;
|
int gobBlockHeightLog2 = (tic[3] >> 3) & 7;
|
||||||
int GobBlockDepthLog2 = (Tic[3] >> 6) & 7;
|
int gobBlockDepthLog2 = (tic[3] >> 6) & 7;
|
||||||
int TileWidthLog2 = (Tic[3] >> 10) & 7;
|
int tileWidthLog2 = (tic[3] >> 10) & 7;
|
||||||
|
|
||||||
int GobBlockHeight = 1 << GobBlockHeightLog2;
|
int gobBlockHeight = 1 << gobBlockHeightLog2;
|
||||||
int GobBlockDepth = 1 << GobBlockDepthLog2;
|
int gobBlockDepth = 1 << gobBlockDepthLog2;
|
||||||
int TileWidth = 1 << TileWidthLog2;
|
int tileWidth = 1 << tileWidthLog2;
|
||||||
|
|
||||||
int Width = ((Tic[4] >> 0) & 0xffff) + 1;
|
int width = ((tic[4] >> 0) & 0xffff) + 1;
|
||||||
int Height = ((Tic[5] >> 0) & 0xffff) + 1;
|
int height = ((tic[5] >> 0) & 0xffff) + 1;
|
||||||
int Depth = ((Tic[5] >> 16) & 0x3fff) + 1;
|
int depth = ((tic[5] >> 16) & 0x3fff) + 1;
|
||||||
|
|
||||||
int LayoutCount = 1;
|
int layoutCount = 1;
|
||||||
|
|
||||||
// TODO: check this
|
// TODO: check this
|
||||||
if (ImageUtils.IsArray(TextureTarget))
|
if (ImageUtils.IsArray(textureTarget))
|
||||||
{
|
{
|
||||||
LayoutCount = Depth;
|
layoutCount = depth;
|
||||||
Depth = 1;
|
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
|
// FIXME: This is a bit hacky but I guess it's fine for now
|
||||||
LayoutCount = 6;
|
layoutCount = 6;
|
||||||
Depth = 1;
|
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
|
// FIXME: This is a really really hacky but I guess it's fine for now
|
||||||
LayoutCount *= 6;
|
layoutCount *= 6;
|
||||||
Depth = 1;
|
depth = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
GalImage Image = new GalImage(
|
GalImage image = new GalImage(
|
||||||
Width,
|
width,
|
||||||
Height,
|
height,
|
||||||
Depth,
|
depth,
|
||||||
LayoutCount,
|
layoutCount,
|
||||||
TileWidth,
|
tileWidth,
|
||||||
GobBlockHeight,
|
gobBlockHeight,
|
||||||
GobBlockDepth,
|
gobBlockDepth,
|
||||||
Layout,
|
layout,
|
||||||
Format,
|
format,
|
||||||
TextureTarget,
|
textureTarget,
|
||||||
MaxMipmapLevel,
|
maxMipmapLevel,
|
||||||
XSource,
|
xSource,
|
||||||
YSource,
|
ySource,
|
||||||
ZSource,
|
zSource,
|
||||||
WSource);
|
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 addressU = (GalTextureWrap)((tsc[0] >> 0) & 7);
|
||||||
GalTextureWrap AddressV = (GalTextureWrap)((Tsc[0] >> 3) & 7);
|
GalTextureWrap addressV = (GalTextureWrap)((tsc[0] >> 3) & 7);
|
||||||
GalTextureWrap AddressP = (GalTextureWrap)((Tsc[0] >> 6) & 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 magFilter = (GalTextureFilter) ((tsc[1] >> 0) & 3);
|
||||||
GalTextureFilter MinFilter = (GalTextureFilter) ((Tsc[1] >> 4) & 3);
|
GalTextureFilter minFilter = (GalTextureFilter) ((tsc[1] >> 4) & 3);
|
||||||
GalTextureMipFilter MipFilter = (GalTextureMipFilter)((Tsc[1] >> 6) & 3);
|
GalTextureMipFilter mipFilter = (GalTextureMipFilter)((tsc[1] >> 6) & 3);
|
||||||
|
|
||||||
GalColorF BorderColor = new GalColorF(
|
GalColorF borderColor = new GalColorF(
|
||||||
BitConverter.Int32BitsToSingle(Tsc[4]),
|
BitConverter.Int32BitsToSingle(tsc[4]),
|
||||||
BitConverter.Int32BitsToSingle(Tsc[5]),
|
BitConverter.Int32BitsToSingle(tsc[5]),
|
||||||
BitConverter.Int32BitsToSingle(Tsc[6]),
|
BitConverter.Int32BitsToSingle(tsc[6]),
|
||||||
BitConverter.Int32BitsToSingle(Tsc[7]));
|
BitConverter.Int32BitsToSingle(tsc[7]));
|
||||||
|
|
||||||
return new GalTextureSampler(
|
return new GalTextureSampler(
|
||||||
AddressU,
|
addressU,
|
||||||
AddressV,
|
addressV,
|
||||||
AddressP,
|
addressP,
|
||||||
MinFilter,
|
minFilter,
|
||||||
MagFilter,
|
magFilter,
|
||||||
MipFilter,
|
mipFilter,
|
||||||
BorderColor,
|
borderColor,
|
||||||
DepthCompare,
|
depthCompare,
|
||||||
DepthCompareFunc);
|
depthCompareFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GalImageFormat GetImageFormat(int[] Tic)
|
private static GalImageFormat GetImageFormat(int[] tic)
|
||||||
{
|
{
|
||||||
GalTextureType RType = (GalTextureType)((Tic[0] >> 7) & 7);
|
GalTextureType rType = (GalTextureType)((tic[0] >> 7) & 7);
|
||||||
GalTextureType GType = (GalTextureType)((Tic[0] >> 10) & 7);
|
GalTextureType gType = (GalTextureType)((tic[0] >> 10) & 7);
|
||||||
GalTextureType BType = (GalTextureType)((Tic[0] >> 13) & 7);
|
GalTextureType bType = (GalTextureType)((tic[0] >> 13) & 7);
|
||||||
GalTextureType AType = (GalTextureType)((Tic[0] >> 16) & 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
|
static class TextureHelper
|
||||||
{
|
{
|
||||||
public static ISwizzle GetSwizzle(GalImage Image)
|
public static ISwizzle GetSwizzle(GalImage image)
|
||||||
{
|
{
|
||||||
int BlockWidth = ImageUtils.GetBlockWidth (Image.Format);
|
int blockWidth = ImageUtils.GetBlockWidth (image.Format);
|
||||||
int BlockHeight = ImageUtils.GetBlockHeight (Image.Format);
|
int blockHeight = ImageUtils.GetBlockHeight (image.Format);
|
||||||
int BlockDepth = ImageUtils.GetBlockDepth (Image.Format);
|
int blockDepth = ImageUtils.GetBlockDepth (image.Format);
|
||||||
int BytesPerPixel = ImageUtils.GetBytesPerPixel(Image.Format);
|
int bytesPerPixel = ImageUtils.GetBytesPerPixel(image.Format);
|
||||||
|
|
||||||
int Width = BitUtils.DivRoundUp(Image.Width, BlockWidth);
|
int width = BitUtils.DivRoundUp(image.Width, blockWidth);
|
||||||
int Height = BitUtils.DivRoundUp(Image.Height, BlockHeight);
|
int height = BitUtils.DivRoundUp(image.Height, blockHeight);
|
||||||
int Depth = BitUtils.DivRoundUp(Image.Depth, BlockDepth);
|
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(
|
return new BlockLinearSwizzle(
|
||||||
Width,
|
width,
|
||||||
Height,
|
height,
|
||||||
Depth,
|
depth,
|
||||||
Image.GobBlockHeight,
|
image.GobBlockHeight,
|
||||||
Image.GobBlockDepth,
|
image.GobBlockDepth,
|
||||||
BytesPerPixel);
|
bytesPerPixel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new LinearSwizzle(Image.Pitch, BytesPerPixel, Width, Height);
|
return new LinearSwizzle(image.Pitch, bytesPerPixel, width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (MemoryManager Memory, long Position) GetMemoryAndPosition(
|
public static (MemoryManager Memory, long Position) GetMemoryAndPosition(
|
||||||
IMemory Memory,
|
IMemory memory,
|
||||||
long Position)
|
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
|
public enum TextureSwizzle
|
||||||
{
|
{
|
||||||
_1dBuffer = 0,
|
_1DBuffer = 0,
|
||||||
PitchColorKey = 1,
|
PitchColorKey = 1,
|
||||||
Pitch = 2,
|
Pitch = 2,
|
||||||
BlockLinear = 3,
|
BlockLinear = 3,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue