Do naming refactoring on Ryujinx.Graphics (#611)
* Renaming part 1 * Renaming part 2 * Renaming part 3 * Renaming part 4 * Renaming part 5 * Renaming part 6 * Renaming part 7 * Renaming part 8 * Renaming part 9 * Renaming part 10 * General cleanup * Thought I got all of these * Apply #595 * Additional renaming * Tweaks from feedback * Rename files
This commit is contained in:
parent
8e71ea0812
commit
1f554c1093
125 changed files with 9121 additions and 9120 deletions
|
@ -6,6 +6,6 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
{
|
||||
int[] Registers { get; }
|
||||
|
||||
void CallMethod(NvGpuVmm Vmm, GpuMethodCall MethCall);
|
||||
void CallMethod(NvGpuVmm vmm, GpuMethodCall methCall);
|
||||
}
|
||||
}
|
|
@ -42,78 +42,78 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
BitwiseNotAnd = 12
|
||||
}
|
||||
|
||||
private NvGpuFifo PFifo;
|
||||
private INvGpuEngine Engine;
|
||||
private NvGpuFifo _pFifo;
|
||||
private INvGpuEngine _engine;
|
||||
|
||||
public Queue<int> Fifo { get; private set; }
|
||||
|
||||
private int[] Gprs;
|
||||
private int[] _gprs;
|
||||
|
||||
private int MethAddr;
|
||||
private int MethIncr;
|
||||
private int _methAddr;
|
||||
private int _methIncr;
|
||||
|
||||
private bool Carry;
|
||||
private bool _carry;
|
||||
|
||||
private int OpCode;
|
||||
private int _opCode;
|
||||
|
||||
private int PipeOp;
|
||||
private int _pipeOp;
|
||||
|
||||
private int Pc;
|
||||
private int _pc;
|
||||
|
||||
public MacroInterpreter(NvGpuFifo PFifo, INvGpuEngine Engine)
|
||||
public MacroInterpreter(NvGpuFifo pFifo, INvGpuEngine engine)
|
||||
{
|
||||
this.PFifo = PFifo;
|
||||
this.Engine = Engine;
|
||||
_pFifo = pFifo;
|
||||
_engine = engine;
|
||||
|
||||
Fifo = new Queue<int>();
|
||||
|
||||
Gprs = new int[8];
|
||||
_gprs = new int[8];
|
||||
}
|
||||
|
||||
public void Execute(NvGpuVmm Vmm, int[] Mme, int Position, int Param)
|
||||
public void Execute(NvGpuVmm vmm, int[] mme, int position, int param)
|
||||
{
|
||||
Reset();
|
||||
|
||||
Gprs[1] = Param;
|
||||
_gprs[1] = param;
|
||||
|
||||
Pc = Position;
|
||||
_pc = position;
|
||||
|
||||
FetchOpCode(Mme);
|
||||
FetchOpCode(mme);
|
||||
|
||||
while (Step(Vmm, Mme));
|
||||
while (Step(vmm, mme));
|
||||
|
||||
//Due to the delay slot, we still need to execute
|
||||
//one more instruction before we actually exit.
|
||||
Step(Vmm, Mme);
|
||||
Step(vmm, mme);
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
for (int Index = 0; Index < Gprs.Length; Index++)
|
||||
for (int index = 0; index < _gprs.Length; index++)
|
||||
{
|
||||
Gprs[Index] = 0;
|
||||
_gprs[index] = 0;
|
||||
}
|
||||
|
||||
MethAddr = 0;
|
||||
MethIncr = 0;
|
||||
_methAddr = 0;
|
||||
_methIncr = 0;
|
||||
|
||||
Carry = false;
|
||||
_carry = false;
|
||||
}
|
||||
|
||||
private bool Step(NvGpuVmm Vmm, int[] Mme)
|
||||
private bool Step(NvGpuVmm vmm, int[] mme)
|
||||
{
|
||||
int BaseAddr = Pc - 1;
|
||||
int baseAddr = _pc - 1;
|
||||
|
||||
FetchOpCode(Mme);
|
||||
FetchOpCode(mme);
|
||||
|
||||
if ((OpCode & 7) < 7)
|
||||
if ((_opCode & 7) < 7)
|
||||
{
|
||||
//Operation produces a value.
|
||||
AssignmentOperation AsgOp = (AssignmentOperation)((OpCode >> 4) & 7);
|
||||
AssignmentOperation asgOp = (AssignmentOperation)((_opCode >> 4) & 7);
|
||||
|
||||
int Result = GetAluResult();
|
||||
int result = GetAluResult();
|
||||
|
||||
switch (AsgOp)
|
||||
switch (asgOp)
|
||||
{
|
||||
//Fetch parameter and ignore result.
|
||||
case AssignmentOperation.IgnoreAndFetch:
|
||||
|
@ -126,7 +126,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
//Move result.
|
||||
case AssignmentOperation.Move:
|
||||
{
|
||||
SetDstGpr(Result);
|
||||
SetDstGpr(result);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -134,9 +134,9 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
//Move result and use as Method Address.
|
||||
case AssignmentOperation.MoveAndSetMaddr:
|
||||
{
|
||||
SetDstGpr(Result);
|
||||
SetDstGpr(result);
|
||||
|
||||
SetMethAddr(Result);
|
||||
SetMethAddr(result);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
{
|
||||
SetDstGpr(FetchParam());
|
||||
|
||||
Send(Vmm, Result);
|
||||
Send(vmm, result);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -154,9 +154,9 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
//Move and send result.
|
||||
case AssignmentOperation.MoveAndSend:
|
||||
{
|
||||
SetDstGpr(Result);
|
||||
SetDstGpr(result);
|
||||
|
||||
Send(Vmm, Result);
|
||||
Send(vmm, result);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
{
|
||||
SetDstGpr(FetchParam());
|
||||
|
||||
SetMethAddr(Result);
|
||||
SetMethAddr(result);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -174,11 +174,11 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
//Move result and use as Method Address, then fetch and send paramter.
|
||||
case AssignmentOperation.MoveAndSetMaddrThenFetchAndSend:
|
||||
{
|
||||
SetDstGpr(Result);
|
||||
SetDstGpr(result);
|
||||
|
||||
SetMethAddr(Result);
|
||||
SetMethAddr(result);
|
||||
|
||||
Send(Vmm, FetchParam());
|
||||
Send(vmm, FetchParam());
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -186,11 +186,11 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
//Move result and use as Method Address, then send bits 17:12 of result.
|
||||
case AssignmentOperation.MoveAndSetMaddrThenSendHigh:
|
||||
{
|
||||
SetDstGpr(Result);
|
||||
SetDstGpr(result);
|
||||
|
||||
SetMethAddr(Result);
|
||||
SetMethAddr(result);
|
||||
|
||||
Send(Vmm, (Result >> 12) & 0x3f);
|
||||
Send(vmm, (result >> 12) & 0x3f);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -199,50 +199,50 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
else
|
||||
{
|
||||
//Branch.
|
||||
bool OnNotZero = ((OpCode >> 4) & 1) != 0;
|
||||
bool onNotZero = ((_opCode >> 4) & 1) != 0;
|
||||
|
||||
bool Taken = OnNotZero
|
||||
bool taken = onNotZero
|
||||
? GetGprA() != 0
|
||||
: GetGprA() == 0;
|
||||
|
||||
if (Taken)
|
||||
if (taken)
|
||||
{
|
||||
Pc = BaseAddr + GetImm();
|
||||
_pc = baseAddr + GetImm();
|
||||
|
||||
bool NoDelays = (OpCode & 0x20) != 0;
|
||||
bool noDelays = (_opCode & 0x20) != 0;
|
||||
|
||||
if (NoDelays)
|
||||
if (noDelays)
|
||||
{
|
||||
FetchOpCode(Mme);
|
||||
FetchOpCode(mme);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Exit = (OpCode & 0x80) != 0;
|
||||
bool exit = (_opCode & 0x80) != 0;
|
||||
|
||||
return !Exit;
|
||||
return !exit;
|
||||
}
|
||||
|
||||
private void FetchOpCode(int[] Mme)
|
||||
private void FetchOpCode(int[] mme)
|
||||
{
|
||||
OpCode = PipeOp;
|
||||
_opCode = _pipeOp;
|
||||
|
||||
PipeOp = Mme[Pc++];
|
||||
_pipeOp = mme[_pc++];
|
||||
}
|
||||
|
||||
private int GetAluResult()
|
||||
{
|
||||
AluOperation Op = (AluOperation)(OpCode & 7);
|
||||
AluOperation op = (AluOperation)(_opCode & 7);
|
||||
|
||||
switch (Op)
|
||||
switch (op)
|
||||
{
|
||||
case AluOperation.AluReg:
|
||||
{
|
||||
AluRegOperation AluOp = (AluRegOperation)((OpCode >> 17) & 0x1f);
|
||||
AluRegOperation aluOp = (AluRegOperation)((_opCode >> 17) & 0x1f);
|
||||
|
||||
return GetAluResult(AluOp, GetGprA(), GetGprB());
|
||||
return GetAluResult(aluOp, GetGprA(), GetGprB());
|
||||
}
|
||||
|
||||
case AluOperation.AddImmediate:
|
||||
|
@ -254,40 +254,40 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
case AluOperation.BitfieldExtractLslImm:
|
||||
case AluOperation.BitfieldExtractLslReg:
|
||||
{
|
||||
int BfSrcBit = (OpCode >> 17) & 0x1f;
|
||||
int BfSize = (OpCode >> 22) & 0x1f;
|
||||
int BfDstBit = (OpCode >> 27) & 0x1f;
|
||||
int bfSrcBit = (_opCode >> 17) & 0x1f;
|
||||
int bfSize = (_opCode >> 22) & 0x1f;
|
||||
int bfDstBit = (_opCode >> 27) & 0x1f;
|
||||
|
||||
int BfMask = (1 << BfSize) - 1;
|
||||
int bfMask = (1 << bfSize) - 1;
|
||||
|
||||
int Dst = GetGprA();
|
||||
int Src = GetGprB();
|
||||
int dst = GetGprA();
|
||||
int src = GetGprB();
|
||||
|
||||
switch (Op)
|
||||
switch (op)
|
||||
{
|
||||
case AluOperation.BitfieldReplace:
|
||||
{
|
||||
Src = (int)((uint)Src >> BfSrcBit) & BfMask;
|
||||
src = (int)((uint)src >> bfSrcBit) & bfMask;
|
||||
|
||||
Dst &= ~(BfMask << BfDstBit);
|
||||
dst &= ~(bfMask << bfDstBit);
|
||||
|
||||
Dst |= Src << BfDstBit;
|
||||
dst |= src << bfDstBit;
|
||||
|
||||
return Dst;
|
||||
return dst;
|
||||
}
|
||||
|
||||
case AluOperation.BitfieldExtractLslImm:
|
||||
{
|
||||
Src = (int)((uint)Src >> Dst) & BfMask;
|
||||
src = (int)((uint)src >> dst) & bfMask;
|
||||
|
||||
return Src << BfDstBit;
|
||||
return src << bfDstBit;
|
||||
}
|
||||
|
||||
case AluOperation.BitfieldExtractLslReg:
|
||||
{
|
||||
Src = (int)((uint)Src >> BfSrcBit) & BfMask;
|
||||
src = (int)((uint)src >> bfSrcBit) & bfMask;
|
||||
|
||||
return Src << Dst;
|
||||
return src << dst;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,117 +300,117 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException(nameof(OpCode));
|
||||
throw new ArgumentException(nameof(_opCode));
|
||||
}
|
||||
|
||||
private int GetAluResult(AluRegOperation AluOp, int A, int B)
|
||||
private int GetAluResult(AluRegOperation aluOp, int a, int b)
|
||||
{
|
||||
switch (AluOp)
|
||||
switch (aluOp)
|
||||
{
|
||||
case AluRegOperation.Add:
|
||||
{
|
||||
ulong Result = (ulong)A + (ulong)B;
|
||||
ulong result = (ulong)a + (ulong)b;
|
||||
|
||||
Carry = Result > 0xffffffff;
|
||||
_carry = result > 0xffffffff;
|
||||
|
||||
return (int)Result;
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
case AluRegOperation.AddWithCarry:
|
||||
{
|
||||
ulong Result = (ulong)A + (ulong)B + (Carry ? 1UL : 0UL);
|
||||
ulong result = (ulong)a + (ulong)b + (_carry ? 1UL : 0UL);
|
||||
|
||||
Carry = Result > 0xffffffff;
|
||||
_carry = result > 0xffffffff;
|
||||
|
||||
return (int)Result;
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
case AluRegOperation.Subtract:
|
||||
{
|
||||
ulong Result = (ulong)A - (ulong)B;
|
||||
ulong result = (ulong)a - (ulong)b;
|
||||
|
||||
Carry = Result < 0x100000000;
|
||||
_carry = result < 0x100000000;
|
||||
|
||||
return (int)Result;
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
case AluRegOperation.SubtractWithBorrow:
|
||||
{
|
||||
ulong Result = (ulong)A - (ulong)B - (Carry ? 0UL : 1UL);
|
||||
ulong result = (ulong)a - (ulong)b - (_carry ? 0UL : 1UL);
|
||||
|
||||
Carry = Result < 0x100000000;
|
||||
_carry = result < 0x100000000;
|
||||
|
||||
return (int)Result;
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
case AluRegOperation.BitwiseExclusiveOr: return A ^ B;
|
||||
case AluRegOperation.BitwiseOr: return A | B;
|
||||
case AluRegOperation.BitwiseAnd: return A & B;
|
||||
case AluRegOperation.BitwiseAndNot: return A & ~B;
|
||||
case AluRegOperation.BitwiseNotAnd: return ~(A & B);
|
||||
case AluRegOperation.BitwiseExclusiveOr: return a ^ b;
|
||||
case AluRegOperation.BitwiseOr: return a | b;
|
||||
case AluRegOperation.BitwiseAnd: return a & b;
|
||||
case AluRegOperation.BitwiseAndNot: return a & ~b;
|
||||
case AluRegOperation.BitwiseNotAnd: return ~(a & b);
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(AluOp));
|
||||
throw new ArgumentOutOfRangeException(nameof(aluOp));
|
||||
}
|
||||
|
||||
private int GetImm()
|
||||
{
|
||||
//Note: The immediate is signed, the sign-extension is intended here.
|
||||
return OpCode >> 14;
|
||||
return _opCode >> 14;
|
||||
}
|
||||
|
||||
private void SetMethAddr(int Value)
|
||||
private void SetMethAddr(int value)
|
||||
{
|
||||
MethAddr = (Value >> 0) & 0xfff;
|
||||
MethIncr = (Value >> 12) & 0x3f;
|
||||
_methAddr = (value >> 0) & 0xfff;
|
||||
_methIncr = (value >> 12) & 0x3f;
|
||||
}
|
||||
|
||||
private void SetDstGpr(int Value)
|
||||
private void SetDstGpr(int value)
|
||||
{
|
||||
Gprs[(OpCode >> 8) & 7] = Value;
|
||||
_gprs[(_opCode >> 8) & 7] = value;
|
||||
}
|
||||
|
||||
private int GetGprA()
|
||||
{
|
||||
return GetGprValue((OpCode >> 11) & 7);
|
||||
return GetGprValue((_opCode >> 11) & 7);
|
||||
}
|
||||
|
||||
private int GetGprB()
|
||||
{
|
||||
return GetGprValue((OpCode >> 14) & 7);
|
||||
return GetGprValue((_opCode >> 14) & 7);
|
||||
}
|
||||
|
||||
private int GetGprValue(int Index)
|
||||
private int GetGprValue(int index)
|
||||
{
|
||||
return Index != 0 ? Gprs[Index] : 0;
|
||||
return index != 0 ? _gprs[index] : 0;
|
||||
}
|
||||
|
||||
private int FetchParam()
|
||||
{
|
||||
int Value;
|
||||
int value;
|
||||
|
||||
if (!Fifo.TryDequeue(out Value))
|
||||
if (!Fifo.TryDequeue(out value))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Gpu, "Macro attempted to fetch an inexistent argument.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Value;
|
||||
return value;
|
||||
}
|
||||
|
||||
private int Read(int Reg)
|
||||
private int Read(int reg)
|
||||
{
|
||||
return Engine.Registers[Reg];
|
||||
return _engine.Registers[reg];
|
||||
}
|
||||
|
||||
private void Send(NvGpuVmm Vmm, int Value)
|
||||
private void Send(NvGpuVmm vmm, int value)
|
||||
{
|
||||
GpuMethodCall MethCall = new GpuMethodCall(MethAddr, Value);
|
||||
GpuMethodCall methCall = new GpuMethodCall(_methAddr, value);
|
||||
|
||||
Engine.CallMethod(Vmm, MethCall);
|
||||
_engine.CallMethod(vmm, methCall);
|
||||
|
||||
MethAddr += MethIncr;
|
||||
_methAddr += _methIncr;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.Gal;
|
||||
using Ryujinx.Graphics.Memory;
|
||||
using Ryujinx.Graphics.Texture;
|
||||
|
@ -20,187 +19,187 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
|
||||
public int[] Registers { get; private set; }
|
||||
|
||||
private NvGpu Gpu;
|
||||
private NvGpu _gpu;
|
||||
|
||||
public NvGpuEngine2d(NvGpu Gpu)
|
||||
public NvGpuEngine2d(NvGpu gpu)
|
||||
{
|
||||
this.Gpu = Gpu;
|
||||
_gpu = gpu;
|
||||
|
||||
Registers = new int[0x238];
|
||||
}
|
||||
|
||||
public void CallMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
||||
public void CallMethod(NvGpuVmm vmm, GpuMethodCall methCall)
|
||||
{
|
||||
WriteRegister(MethCall);
|
||||
WriteRegister(methCall);
|
||||
|
||||
if ((NvGpuEngine2dReg)MethCall.Method == NvGpuEngine2dReg.BlitSrcYInt)
|
||||
if ((NvGpuEngine2dReg)methCall.Method == NvGpuEngine2dReg.BlitSrcYInt)
|
||||
{
|
||||
TextureCopy(Vmm);
|
||||
TextureCopy(vmm);
|
||||
}
|
||||
}
|
||||
|
||||
private void TextureCopy(NvGpuVmm Vmm)
|
||||
private void TextureCopy(NvGpuVmm vmm)
|
||||
{
|
||||
CopyOperation Operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation);
|
||||
CopyOperation operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation);
|
||||
|
||||
int DstFormat = ReadRegister(NvGpuEngine2dReg.DstFormat);
|
||||
bool DstLinear = ReadRegister(NvGpuEngine2dReg.DstLinear) != 0;
|
||||
int DstWidth = ReadRegister(NvGpuEngine2dReg.DstWidth);
|
||||
int DstHeight = ReadRegister(NvGpuEngine2dReg.DstHeight);
|
||||
int DstDepth = ReadRegister(NvGpuEngine2dReg.DstDepth);
|
||||
int DstLayer = ReadRegister(NvGpuEngine2dReg.DstLayer);
|
||||
int DstPitch = ReadRegister(NvGpuEngine2dReg.DstPitch);
|
||||
int DstBlkDim = ReadRegister(NvGpuEngine2dReg.DstBlockDimensions);
|
||||
int dstFormat = ReadRegister(NvGpuEngine2dReg.DstFormat);
|
||||
bool dstLinear = ReadRegister(NvGpuEngine2dReg.DstLinear) != 0;
|
||||
int dstWidth = ReadRegister(NvGpuEngine2dReg.DstWidth);
|
||||
int dstHeight = ReadRegister(NvGpuEngine2dReg.DstHeight);
|
||||
int dstDepth = ReadRegister(NvGpuEngine2dReg.DstDepth);
|
||||
int dstLayer = ReadRegister(NvGpuEngine2dReg.DstLayer);
|
||||
int dstPitch = ReadRegister(NvGpuEngine2dReg.DstPitch);
|
||||
int dstBlkDim = ReadRegister(NvGpuEngine2dReg.DstBlockDimensions);
|
||||
|
||||
int SrcFormat = ReadRegister(NvGpuEngine2dReg.SrcFormat);
|
||||
bool SrcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0;
|
||||
int SrcWidth = ReadRegister(NvGpuEngine2dReg.SrcWidth);
|
||||
int SrcHeight = ReadRegister(NvGpuEngine2dReg.SrcHeight);
|
||||
int SrcDepth = ReadRegister(NvGpuEngine2dReg.SrcDepth);
|
||||
int SrcLayer = ReadRegister(NvGpuEngine2dReg.SrcLayer);
|
||||
int SrcPitch = ReadRegister(NvGpuEngine2dReg.SrcPitch);
|
||||
int SrcBlkDim = ReadRegister(NvGpuEngine2dReg.SrcBlockDimensions);
|
||||
int srcFormat = ReadRegister(NvGpuEngine2dReg.SrcFormat);
|
||||
bool srcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0;
|
||||
int srcWidth = ReadRegister(NvGpuEngine2dReg.SrcWidth);
|
||||
int srcHeight = ReadRegister(NvGpuEngine2dReg.SrcHeight);
|
||||
int srcDepth = ReadRegister(NvGpuEngine2dReg.SrcDepth);
|
||||
int srcLayer = ReadRegister(NvGpuEngine2dReg.SrcLayer);
|
||||
int srcPitch = ReadRegister(NvGpuEngine2dReg.SrcPitch);
|
||||
int srcBlkDim = ReadRegister(NvGpuEngine2dReg.SrcBlockDimensions);
|
||||
|
||||
int DstBlitX = ReadRegister(NvGpuEngine2dReg.BlitDstX);
|
||||
int DstBlitY = ReadRegister(NvGpuEngine2dReg.BlitDstY);
|
||||
int DstBlitW = ReadRegister(NvGpuEngine2dReg.BlitDstW);
|
||||
int DstBlitH = ReadRegister(NvGpuEngine2dReg.BlitDstH);
|
||||
int dstBlitX = ReadRegister(NvGpuEngine2dReg.BlitDstX);
|
||||
int dstBlitY = ReadRegister(NvGpuEngine2dReg.BlitDstY);
|
||||
int dstBlitW = ReadRegister(NvGpuEngine2dReg.BlitDstW);
|
||||
int dstBlitH = ReadRegister(NvGpuEngine2dReg.BlitDstH);
|
||||
|
||||
long BlitDuDx = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDuDxFract);
|
||||
long BlitDvDy = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDvDyFract);
|
||||
long blitDuDx = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDuDxFract);
|
||||
long blitDvDy = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDvDyFract);
|
||||
|
||||
long SrcBlitX = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitSrcXFract);
|
||||
long SrcBlitY = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitSrcYFract);
|
||||
long srcBlitX = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitSrcXFract);
|
||||
long srcBlitY = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitSrcYFract);
|
||||
|
||||
GalImageFormat SrcImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)SrcFormat);
|
||||
GalImageFormat DstImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)DstFormat);
|
||||
GalImageFormat srcImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)srcFormat);
|
||||
GalImageFormat dstImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)dstFormat);
|
||||
|
||||
GalMemoryLayout SrcLayout = GetLayout(SrcLinear);
|
||||
GalMemoryLayout DstLayout = GetLayout(DstLinear);
|
||||
GalMemoryLayout srcLayout = GetLayout(srcLinear);
|
||||
GalMemoryLayout dstLayout = GetLayout(dstLinear);
|
||||
|
||||
int SrcBlockHeight = 1 << ((SrcBlkDim >> 4) & 0xf);
|
||||
int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf);
|
||||
int srcBlockHeight = 1 << ((srcBlkDim >> 4) & 0xf);
|
||||
int dstBlockHeight = 1 << ((dstBlkDim >> 4) & 0xf);
|
||||
|
||||
long SrcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress);
|
||||
long DstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress);
|
||||
long srcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress);
|
||||
long dstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress);
|
||||
|
||||
long SrcKey = Vmm.GetPhysicalAddress(SrcAddress);
|
||||
long DstKey = Vmm.GetPhysicalAddress(DstAddress);
|
||||
long srcKey = vmm.GetPhysicalAddress(srcAddress);
|
||||
long dstKey = vmm.GetPhysicalAddress(dstAddress);
|
||||
|
||||
bool IsSrcLayered = false;
|
||||
bool IsDstLayered = false;
|
||||
bool isSrcLayered = false;
|
||||
bool isDstLayered = false;
|
||||
|
||||
GalTextureTarget SrcTarget = GalTextureTarget.TwoD;
|
||||
GalTextureTarget srcTarget = GalTextureTarget.TwoD;
|
||||
|
||||
if (SrcDepth != 0)
|
||||
if (srcDepth != 0)
|
||||
{
|
||||
SrcTarget = GalTextureTarget.TwoDArray;
|
||||
SrcDepth++;
|
||||
IsSrcLayered = true;
|
||||
srcTarget = GalTextureTarget.TwoDArray;
|
||||
srcDepth++;
|
||||
isSrcLayered = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SrcDepth = 1;
|
||||
srcDepth = 1;
|
||||
}
|
||||
|
||||
GalTextureTarget DstTarget = GalTextureTarget.TwoD;
|
||||
GalTextureTarget dstTarget = GalTextureTarget.TwoD;
|
||||
|
||||
if (DstDepth != 0)
|
||||
if (dstDepth != 0)
|
||||
{
|
||||
DstTarget = GalTextureTarget.TwoDArray;
|
||||
DstDepth++;
|
||||
IsDstLayered = true;
|
||||
dstTarget = GalTextureTarget.TwoDArray;
|
||||
dstDepth++;
|
||||
isDstLayered = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DstDepth = 1;
|
||||
dstDepth = 1;
|
||||
}
|
||||
|
||||
GalImage SrcTexture = new GalImage(
|
||||
SrcWidth,
|
||||
SrcHeight,
|
||||
1, SrcDepth, 1,
|
||||
SrcBlockHeight, 1,
|
||||
SrcLayout,
|
||||
SrcImgFormat,
|
||||
SrcTarget);
|
||||
GalImage srcTexture = new GalImage(
|
||||
srcWidth,
|
||||
srcHeight,
|
||||
1, srcDepth, 1,
|
||||
srcBlockHeight, 1,
|
||||
srcLayout,
|
||||
srcImgFormat,
|
||||
srcTarget);
|
||||
|
||||
GalImage DstTexture = new GalImage(
|
||||
DstWidth,
|
||||
DstHeight,
|
||||
1, DstDepth, 1,
|
||||
DstBlockHeight, 1,
|
||||
DstLayout,
|
||||
DstImgFormat,
|
||||
DstTarget);
|
||||
GalImage dstTexture = new GalImage(
|
||||
dstWidth,
|
||||
dstHeight,
|
||||
1, dstDepth, 1,
|
||||
dstBlockHeight, 1,
|
||||
dstLayout,
|
||||
dstImgFormat,
|
||||
dstTarget);
|
||||
|
||||
SrcTexture.Pitch = SrcPitch;
|
||||
DstTexture.Pitch = DstPitch;
|
||||
srcTexture.Pitch = srcPitch;
|
||||
dstTexture.Pitch = dstPitch;
|
||||
|
||||
long GetLayerOffset(GalImage Image, int Layer)
|
||||
long GetLayerOffset(GalImage image, int layer)
|
||||
{
|
||||
int TargetMipLevel = Image.MaxMipmapLevel <= 1 ? 1 : Image.MaxMipmapLevel - 1;
|
||||
return ImageUtils.GetLayerOffset(Image, TargetMipLevel) * Layer;
|
||||
int targetMipLevel = image.MaxMipmapLevel <= 1 ? 1 : image.MaxMipmapLevel - 1;
|
||||
return ImageUtils.GetLayerOffset(image, targetMipLevel) * layer;
|
||||
}
|
||||
|
||||
int SrcLayerIndex = -1;
|
||||
int srcLayerIndex = -1;
|
||||
|
||||
if (IsSrcLayered && Gpu.ResourceManager.TryGetTextureLayer(SrcKey, out SrcLayerIndex) && SrcLayerIndex != 0)
|
||||
if (isSrcLayered && _gpu.ResourceManager.TryGetTextureLayer(srcKey, out srcLayerIndex) && srcLayerIndex != 0)
|
||||
{
|
||||
SrcKey = SrcKey - GetLayerOffset(SrcTexture, SrcLayerIndex);
|
||||
srcKey = srcKey - GetLayerOffset(srcTexture, srcLayerIndex);
|
||||
}
|
||||
|
||||
int DstLayerIndex = -1;
|
||||
int dstLayerIndex = -1;
|
||||
|
||||
if (IsDstLayered && Gpu.ResourceManager.TryGetTextureLayer(DstKey, out DstLayerIndex) && DstLayerIndex != 0)
|
||||
if (isDstLayered && _gpu.ResourceManager.TryGetTextureLayer(dstKey, out dstLayerIndex) && dstLayerIndex != 0)
|
||||
{
|
||||
DstKey = DstKey - GetLayerOffset(DstTexture, DstLayerIndex);
|
||||
dstKey = dstKey - GetLayerOffset(dstTexture, dstLayerIndex);
|
||||
}
|
||||
|
||||
Gpu.ResourceManager.SendTexture(Vmm, SrcKey, SrcTexture);
|
||||
Gpu.ResourceManager.SendTexture(Vmm, DstKey, DstTexture);
|
||||
_gpu.ResourceManager.SendTexture(vmm, srcKey, srcTexture);
|
||||
_gpu.ResourceManager.SendTexture(vmm, dstKey, dstTexture);
|
||||
|
||||
if (IsSrcLayered && SrcLayerIndex == -1)
|
||||
if (isSrcLayered && srcLayerIndex == -1)
|
||||
{
|
||||
for (int Layer = 0; Layer < SrcTexture.LayerCount; Layer++)
|
||||
for (int layer = 0; layer < srcTexture.LayerCount; layer++)
|
||||
{
|
||||
Gpu.ResourceManager.SetTextureArrayLayer(SrcKey + GetLayerOffset(SrcTexture, Layer), Layer);
|
||||
_gpu.ResourceManager.SetTextureArrayLayer(srcKey + GetLayerOffset(srcTexture, layer), layer);
|
||||
}
|
||||
|
||||
SrcLayerIndex = 0;
|
||||
srcLayerIndex = 0;
|
||||
}
|
||||
|
||||
if (IsDstLayered && DstLayerIndex == -1)
|
||||
if (isDstLayered && dstLayerIndex == -1)
|
||||
{
|
||||
for (int Layer = 0; Layer < DstTexture.LayerCount; Layer++)
|
||||
for (int layer = 0; layer < dstTexture.LayerCount; layer++)
|
||||
{
|
||||
Gpu.ResourceManager.SetTextureArrayLayer(DstKey + GetLayerOffset(DstTexture, Layer), Layer);
|
||||
_gpu.ResourceManager.SetTextureArrayLayer(dstKey + GetLayerOffset(dstTexture, layer), layer);
|
||||
}
|
||||
|
||||
DstLayerIndex = 0;
|
||||
dstLayerIndex = 0;
|
||||
}
|
||||
|
||||
int SrcBlitX1 = (int)(SrcBlitX >> 32);
|
||||
int SrcBlitY1 = (int)(SrcBlitY >> 32);
|
||||
int srcBlitX1 = (int)(srcBlitX >> 32);
|
||||
int srcBlitY1 = (int)(srcBlitY >> 32);
|
||||
|
||||
int SrcBlitX2 = (int)(SrcBlitX + DstBlitW * BlitDuDx >> 32);
|
||||
int SrcBlitY2 = (int)(SrcBlitY + DstBlitH * BlitDvDy >> 32);
|
||||
int srcBlitX2 = (int)(srcBlitX + dstBlitW * blitDuDx >> 32);
|
||||
int srcBlitY2 = (int)(srcBlitY + dstBlitH * blitDvDy >> 32);
|
||||
|
||||
Gpu.Renderer.RenderTarget.Copy(
|
||||
SrcTexture,
|
||||
DstTexture,
|
||||
SrcKey,
|
||||
DstKey,
|
||||
SrcLayerIndex,
|
||||
DstLayerIndex,
|
||||
SrcBlitX1,
|
||||
SrcBlitY1,
|
||||
SrcBlitX2,
|
||||
SrcBlitY2,
|
||||
DstBlitX,
|
||||
DstBlitY,
|
||||
DstBlitX + DstBlitW,
|
||||
DstBlitY + DstBlitH);
|
||||
_gpu.Renderer.RenderTarget.Copy(
|
||||
srcTexture,
|
||||
dstTexture,
|
||||
srcKey,
|
||||
dstKey,
|
||||
srcLayerIndex,
|
||||
dstLayerIndex,
|
||||
srcBlitX1,
|
||||
srcBlitY1,
|
||||
srcBlitX2,
|
||||
srcBlitY2,
|
||||
dstBlitX,
|
||||
dstBlitY,
|
||||
dstBlitX + dstBlitW,
|
||||
dstBlitY + dstBlitH);
|
||||
|
||||
//Do a guest side copy aswell. This is necessary when
|
||||
//the texture is modified by the guest, however it doesn't
|
||||
|
@ -209,51 +208,51 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
|
||||
// FIXME: SUPPORT MULTILAYER CORRECTLY HERE (this will cause weird stuffs on the first layer)
|
||||
ImageUtils.CopyTexture(
|
||||
Vmm,
|
||||
SrcTexture,
|
||||
DstTexture,
|
||||
SrcAddress,
|
||||
DstAddress,
|
||||
SrcBlitX1,
|
||||
SrcBlitY1,
|
||||
DstBlitX,
|
||||
DstBlitY,
|
||||
DstBlitW,
|
||||
DstBlitH);
|
||||
vmm,
|
||||
srcTexture,
|
||||
dstTexture,
|
||||
srcAddress,
|
||||
dstAddress,
|
||||
srcBlitX1,
|
||||
srcBlitY1,
|
||||
dstBlitX,
|
||||
dstBlitY,
|
||||
dstBlitW,
|
||||
dstBlitH);
|
||||
|
||||
Vmm.IsRegionModified(DstKey, ImageUtils.GetSize(DstTexture), NvGpuBufferType.Texture);
|
||||
vmm.IsRegionModified(dstKey, ImageUtils.GetSize(dstTexture), NvGpuBufferType.Texture);
|
||||
}
|
||||
|
||||
private static GalMemoryLayout GetLayout(bool Linear)
|
||||
private static GalMemoryLayout GetLayout(bool linear)
|
||||
{
|
||||
return Linear
|
||||
return linear
|
||||
? GalMemoryLayout.Pitch
|
||||
: GalMemoryLayout.BlockLinear;
|
||||
}
|
||||
|
||||
private long MakeInt64From2xInt32(NvGpuEngine2dReg Reg)
|
||||
private long MakeInt64From2xInt32(NvGpuEngine2dReg reg)
|
||||
{
|
||||
return
|
||||
(long)Registers[(int)Reg + 0] << 32 |
|
||||
(uint)Registers[(int)Reg + 1];
|
||||
(long)Registers[(int)reg + 0] << 32 |
|
||||
(uint)Registers[(int)reg + 1];
|
||||
}
|
||||
|
||||
private void WriteRegister(GpuMethodCall MethCall)
|
||||
private void WriteRegister(GpuMethodCall methCall)
|
||||
{
|
||||
Registers[MethCall.Method] = MethCall.Argument;
|
||||
Registers[methCall.Method] = methCall.Argument;
|
||||
}
|
||||
|
||||
private long ReadRegisterFixed1_31_32(NvGpuEngine2dReg Reg)
|
||||
private long ReadRegisterFixed1_31_32(NvGpuEngine2dReg reg)
|
||||
{
|
||||
long Low = (uint)ReadRegister(Reg + 0);
|
||||
long High = (uint)ReadRegister(Reg + 1);
|
||||
long low = (uint)ReadRegister(reg + 0);
|
||||
long high = (uint)ReadRegister(reg + 1);
|
||||
|
||||
return Low | (High << 32);
|
||||
return low | (high << 32);
|
||||
}
|
||||
|
||||
private int ReadRegister(NvGpuEngine2dReg Reg)
|
||||
private int ReadRegister(NvGpuEngine2dReg reg)
|
||||
{
|
||||
return Registers[(int)Reg];
|
||||
return Registers[(int)reg];
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -32,13 +32,13 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
StencilBackMask = 0x3d6,
|
||||
StencilBackFuncMask = 0x3d7,
|
||||
ColorMaskCommon = 0x3e4,
|
||||
RTSeparateFragData = 0x3eb,
|
||||
RtSeparateFragData = 0x3eb,
|
||||
ZetaAddress = 0x3f8,
|
||||
ZetaFormat = 0x3fa,
|
||||
ZetaBlockDimensions = 0x3fb,
|
||||
ZetaLayerStride = 0x3fc,
|
||||
VertexAttribNFormat = 0x458,
|
||||
RTControl = 0x487,
|
||||
RtControl = 0x487,
|
||||
ZetaHoriz = 0x48a,
|
||||
ZetaVert = 0x48b,
|
||||
ZetaArrayMode = 0x48c,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.Memory;
|
||||
using Ryujinx.Graphics.Texture;
|
||||
using System.Collections.Generic;
|
||||
|
@ -9,188 +8,188 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
{
|
||||
public int[] Registers { get; private set; }
|
||||
|
||||
private NvGpu Gpu;
|
||||
private NvGpu _gpu;
|
||||
|
||||
private Dictionary<int, NvGpuMethod> Methods;
|
||||
private Dictionary<int, NvGpuMethod> _methods;
|
||||
|
||||
public NvGpuEngineM2mf(NvGpu Gpu)
|
||||
public NvGpuEngineM2mf(NvGpu gpu)
|
||||
{
|
||||
this.Gpu = Gpu;
|
||||
_gpu = gpu;
|
||||
|
||||
Registers = new int[0x1d6];
|
||||
|
||||
Methods = new Dictionary<int, NvGpuMethod>();
|
||||
_methods = new Dictionary<int, NvGpuMethod>();
|
||||
|
||||
void AddMethod(int Meth, int Count, int Stride, NvGpuMethod Method)
|
||||
void AddMethod(int meth, int count, int stride, NvGpuMethod method)
|
||||
{
|
||||
while (Count-- > 0)
|
||||
while (count-- > 0)
|
||||
{
|
||||
Methods.Add(Meth, Method);
|
||||
_methods.Add(meth, method);
|
||||
|
||||
Meth += Stride;
|
||||
meth += stride;
|
||||
}
|
||||
}
|
||||
|
||||
AddMethod(0xc0, 1, 1, Execute);
|
||||
}
|
||||
|
||||
public void CallMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
||||
public void CallMethod(NvGpuVmm vmm, GpuMethodCall methCall)
|
||||
{
|
||||
if (Methods.TryGetValue(MethCall.Method, out NvGpuMethod Method))
|
||||
if (_methods.TryGetValue(methCall.Method, out NvGpuMethod method))
|
||||
{
|
||||
Method(Vmm, MethCall);
|
||||
method(vmm, methCall);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteRegister(MethCall);
|
||||
WriteRegister(methCall);
|
||||
}
|
||||
}
|
||||
|
||||
private void Execute(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
||||
private void Execute(NvGpuVmm vmm, GpuMethodCall methCall)
|
||||
{
|
||||
//TODO: Some registers and copy modes are still not implemented.
|
||||
int Control = MethCall.Argument;
|
||||
int control = methCall.Argument;
|
||||
|
||||
bool SrcLinear = ((Control >> 7) & 1) != 0;
|
||||
bool DstLinear = ((Control >> 8) & 1) != 0;
|
||||
bool Copy2d = ((Control >> 9) & 1) != 0;
|
||||
bool srcLinear = ((control >> 7) & 1) != 0;
|
||||
bool dstLinear = ((control >> 8) & 1) != 0;
|
||||
bool copy2D = ((control >> 9) & 1) != 0;
|
||||
|
||||
long SrcAddress = MakeInt64From2xInt32(NvGpuEngineM2mfReg.SrcAddress);
|
||||
long DstAddress = MakeInt64From2xInt32(NvGpuEngineM2mfReg.DstAddress);
|
||||
long srcAddress = MakeInt64From2xInt32(NvGpuEngineM2mfReg.SrcAddress);
|
||||
long dstAddress = MakeInt64From2xInt32(NvGpuEngineM2mfReg.DstAddress);
|
||||
|
||||
int SrcPitch = ReadRegister(NvGpuEngineM2mfReg.SrcPitch);
|
||||
int DstPitch = ReadRegister(NvGpuEngineM2mfReg.DstPitch);
|
||||
int srcPitch = ReadRegister(NvGpuEngineM2mfReg.SrcPitch);
|
||||
int dstPitch = ReadRegister(NvGpuEngineM2mfReg.DstPitch);
|
||||
|
||||
int XCount = ReadRegister(NvGpuEngineM2mfReg.XCount);
|
||||
int YCount = ReadRegister(NvGpuEngineM2mfReg.YCount);
|
||||
int xCount = ReadRegister(NvGpuEngineM2mfReg.XCount);
|
||||
int yCount = ReadRegister(NvGpuEngineM2mfReg.YCount);
|
||||
|
||||
int Swizzle = ReadRegister(NvGpuEngineM2mfReg.Swizzle);
|
||||
int swizzle = ReadRegister(NvGpuEngineM2mfReg.Swizzle);
|
||||
|
||||
int DstBlkDim = ReadRegister(NvGpuEngineM2mfReg.DstBlkDim);
|
||||
int DstSizeX = ReadRegister(NvGpuEngineM2mfReg.DstSizeX);
|
||||
int DstSizeY = ReadRegister(NvGpuEngineM2mfReg.DstSizeY);
|
||||
int DstSizeZ = ReadRegister(NvGpuEngineM2mfReg.DstSizeZ);
|
||||
int DstPosXY = ReadRegister(NvGpuEngineM2mfReg.DstPosXY);
|
||||
int DstPosZ = ReadRegister(NvGpuEngineM2mfReg.DstPosZ);
|
||||
int dstBlkDim = ReadRegister(NvGpuEngineM2mfReg.DstBlkDim);
|
||||
int dstSizeX = ReadRegister(NvGpuEngineM2mfReg.DstSizeX);
|
||||
int dstSizeY = ReadRegister(NvGpuEngineM2mfReg.DstSizeY);
|
||||
int dstSizeZ = ReadRegister(NvGpuEngineM2mfReg.DstSizeZ);
|
||||
int dstPosXY = ReadRegister(NvGpuEngineM2mfReg.DstPosXY);
|
||||
int dstPosZ = ReadRegister(NvGpuEngineM2mfReg.DstPosZ);
|
||||
|
||||
int SrcBlkDim = ReadRegister(NvGpuEngineM2mfReg.SrcBlkDim);
|
||||
int SrcSizeX = ReadRegister(NvGpuEngineM2mfReg.SrcSizeX);
|
||||
int SrcSizeY = ReadRegister(NvGpuEngineM2mfReg.SrcSizeY);
|
||||
int SrcSizeZ = ReadRegister(NvGpuEngineM2mfReg.SrcSizeZ);
|
||||
int SrcPosXY = ReadRegister(NvGpuEngineM2mfReg.SrcPosXY);
|
||||
int SrcPosZ = ReadRegister(NvGpuEngineM2mfReg.SrcPosZ);
|
||||
int srcBlkDim = ReadRegister(NvGpuEngineM2mfReg.SrcBlkDim);
|
||||
int srcSizeX = ReadRegister(NvGpuEngineM2mfReg.SrcSizeX);
|
||||
int srcSizeY = ReadRegister(NvGpuEngineM2mfReg.SrcSizeY);
|
||||
int srcSizeZ = ReadRegister(NvGpuEngineM2mfReg.SrcSizeZ);
|
||||
int srcPosXY = ReadRegister(NvGpuEngineM2mfReg.SrcPosXY);
|
||||
int srcPosZ = ReadRegister(NvGpuEngineM2mfReg.SrcPosZ);
|
||||
|
||||
int SrcCpp = ((Swizzle >> 20) & 7) + 1;
|
||||
int DstCpp = ((Swizzle >> 24) & 7) + 1;
|
||||
int srcCpp = ((swizzle >> 20) & 7) + 1;
|
||||
int dstCpp = ((swizzle >> 24) & 7) + 1;
|
||||
|
||||
int DstPosX = (DstPosXY >> 0) & 0xffff;
|
||||
int DstPosY = (DstPosXY >> 16) & 0xffff;
|
||||
int dstPosX = (dstPosXY >> 0) & 0xffff;
|
||||
int dstPosY = (dstPosXY >> 16) & 0xffff;
|
||||
|
||||
int SrcPosX = (SrcPosXY >> 0) & 0xffff;
|
||||
int SrcPosY = (SrcPosXY >> 16) & 0xffff;
|
||||
int srcPosX = (srcPosXY >> 0) & 0xffff;
|
||||
int srcPosY = (srcPosXY >> 16) & 0xffff;
|
||||
|
||||
int SrcBlockHeight = 1 << ((SrcBlkDim >> 4) & 0xf);
|
||||
int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf);
|
||||
int srcBlockHeight = 1 << ((srcBlkDim >> 4) & 0xf);
|
||||
int dstBlockHeight = 1 << ((dstBlkDim >> 4) & 0xf);
|
||||
|
||||
long SrcPA = Vmm.GetPhysicalAddress(SrcAddress);
|
||||
long DstPA = Vmm.GetPhysicalAddress(DstAddress);
|
||||
long srcPa = vmm.GetPhysicalAddress(srcAddress);
|
||||
long dstPa = vmm.GetPhysicalAddress(dstAddress);
|
||||
|
||||
if (Copy2d)
|
||||
if (copy2D)
|
||||
{
|
||||
if (SrcLinear)
|
||||
if (srcLinear)
|
||||
{
|
||||
SrcPosX = SrcPosY = SrcPosZ = 0;
|
||||
srcPosX = srcPosY = srcPosZ = 0;
|
||||
}
|
||||
|
||||
if (DstLinear)
|
||||
if (dstLinear)
|
||||
{
|
||||
DstPosX = DstPosY = DstPosZ = 0;
|
||||
dstPosX = dstPosY = dstPosZ = 0;
|
||||
}
|
||||
|
||||
if (SrcLinear && DstLinear)
|
||||
if (srcLinear && dstLinear)
|
||||
{
|
||||
for (int Y = 0; Y < YCount; Y++)
|
||||
for (int y = 0; y < yCount; y++)
|
||||
{
|
||||
int SrcOffset = (SrcPosY + Y) * SrcPitch + SrcPosX * SrcCpp;
|
||||
int DstOffset = (DstPosY + Y) * DstPitch + DstPosX * DstCpp;
|
||||
int srcOffset = (srcPosY + y) * srcPitch + srcPosX * srcCpp;
|
||||
int dstOffset = (dstPosY + y) * dstPitch + dstPosX * dstCpp;
|
||||
|
||||
long Src = SrcPA + (uint)SrcOffset;
|
||||
long Dst = DstPA + (uint)DstOffset;
|
||||
long src = srcPa + (uint)srcOffset;
|
||||
long dst = dstPa + (uint)dstOffset;
|
||||
|
||||
Vmm.Memory.CopyBytes(Src, Dst, XCount * SrcCpp);
|
||||
vmm.Memory.CopyBytes(src, dst, xCount * srcCpp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ISwizzle SrcSwizzle;
|
||||
ISwizzle srcSwizzle;
|
||||
|
||||
if (SrcLinear)
|
||||
if (srcLinear)
|
||||
{
|
||||
SrcSwizzle = new LinearSwizzle(SrcPitch, SrcCpp, SrcSizeX, SrcSizeY);
|
||||
srcSwizzle = new LinearSwizzle(srcPitch, srcCpp, srcSizeX, srcSizeY);
|
||||
}
|
||||
else
|
||||
{
|
||||
SrcSwizzle = new BlockLinearSwizzle(
|
||||
SrcSizeX,
|
||||
SrcSizeY, 1,
|
||||
SrcBlockHeight, 1,
|
||||
SrcCpp);
|
||||
srcSwizzle = new BlockLinearSwizzle(
|
||||
srcSizeX,
|
||||
srcSizeY, 1,
|
||||
srcBlockHeight, 1,
|
||||
srcCpp);
|
||||
}
|
||||
|
||||
ISwizzle DstSwizzle;
|
||||
ISwizzle dstSwizzle;
|
||||
|
||||
if (DstLinear)
|
||||
if (dstLinear)
|
||||
{
|
||||
DstSwizzle = new LinearSwizzle(DstPitch, DstCpp, SrcSizeX, SrcSizeY);
|
||||
dstSwizzle = new LinearSwizzle(dstPitch, dstCpp, srcSizeX, srcSizeY);
|
||||
}
|
||||
else
|
||||
{
|
||||
DstSwizzle = new BlockLinearSwizzle(
|
||||
DstSizeX,
|
||||
DstSizeY, 1,
|
||||
DstBlockHeight, 1,
|
||||
DstCpp);
|
||||
dstSwizzle = new BlockLinearSwizzle(
|
||||
dstSizeX,
|
||||
dstSizeY, 1,
|
||||
dstBlockHeight, 1,
|
||||
dstCpp);
|
||||
}
|
||||
|
||||
for (int Y = 0; Y < YCount; Y++)
|
||||
for (int X = 0; X < XCount; X++)
|
||||
for (int y = 0; y < yCount; y++)
|
||||
for (int x = 0; x < xCount; x++)
|
||||
{
|
||||
int SrcOffset = SrcSwizzle.GetSwizzleOffset(SrcPosX + X, SrcPosY + Y, 0);
|
||||
int DstOffset = DstSwizzle.GetSwizzleOffset(DstPosX + X, DstPosY + Y, 0);
|
||||
int srcOffset = srcSwizzle.GetSwizzleOffset(srcPosX + x, srcPosY + y, 0);
|
||||
int dstOffset = dstSwizzle.GetSwizzleOffset(dstPosX + x, dstPosY + y, 0);
|
||||
|
||||
long Src = SrcPA + (uint)SrcOffset;
|
||||
long Dst = DstPA + (uint)DstOffset;
|
||||
long src = srcPa + (uint)srcOffset;
|
||||
long dst = dstPa + (uint)dstOffset;
|
||||
|
||||
Vmm.Memory.CopyBytes(Src, Dst, SrcCpp);
|
||||
vmm.Memory.CopyBytes(src, dst, srcCpp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Vmm.Memory.CopyBytes(SrcPA, DstPA, XCount);
|
||||
vmm.Memory.CopyBytes(srcPa, dstPa, xCount);
|
||||
}
|
||||
}
|
||||
|
||||
private long MakeInt64From2xInt32(NvGpuEngineM2mfReg Reg)
|
||||
private long MakeInt64From2xInt32(NvGpuEngineM2mfReg reg)
|
||||
{
|
||||
return
|
||||
(long)Registers[(int)Reg + 0] << 32 |
|
||||
(uint)Registers[(int)Reg + 1];
|
||||
(long)Registers[(int)reg + 0] << 32 |
|
||||
(uint)Registers[(int)reg + 1];
|
||||
}
|
||||
|
||||
private void WriteRegister(GpuMethodCall MethCall)
|
||||
private void WriteRegister(GpuMethodCall methCall)
|
||||
{
|
||||
Registers[MethCall.Method] = MethCall.Argument;
|
||||
Registers[methCall.Method] = methCall.Argument;
|
||||
}
|
||||
|
||||
private int ReadRegister(NvGpuEngineM2mfReg Reg)
|
||||
private int ReadRegister(NvGpuEngineM2mfReg reg)
|
||||
{
|
||||
return Registers[(int)Reg];
|
||||
return Registers[(int)reg];
|
||||
}
|
||||
|
||||
private void WriteRegister(NvGpuEngineM2mfReg Reg, int Value)
|
||||
private void WriteRegister(NvGpuEngineM2mfReg reg, int value)
|
||||
{
|
||||
Registers[(int)Reg] = Value;
|
||||
Registers[(int)reg] = value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.Memory;
|
||||
using Ryujinx.Graphics.Texture;
|
||||
using System.Collections.Generic;
|
||||
|
@ -9,41 +8,41 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
{
|
||||
public int[] Registers { get; private set; }
|
||||
|
||||
private NvGpu Gpu;
|
||||
private NvGpu _gpu;
|
||||
|
||||
private Dictionary<int, NvGpuMethod> Methods;
|
||||
private Dictionary<int, NvGpuMethod> _methods;
|
||||
|
||||
private int CopyStartX;
|
||||
private int CopyStartY;
|
||||
private int _copyStartX;
|
||||
private int _copyStartY;
|
||||
|
||||
private int CopyWidth;
|
||||
private int CopyHeight;
|
||||
private int CopyGobBlockHeight;
|
||||
private int _copyWidth;
|
||||
private int _copyHeight;
|
||||
private int _copyGobBlockHeight;
|
||||
|
||||
private long CopyAddress;
|
||||
private long _copyAddress;
|
||||
|
||||
private int CopyOffset;
|
||||
private int CopySize;
|
||||
private int _copyOffset;
|
||||
private int _copySize;
|
||||
|
||||
private bool CopyLinear;
|
||||
private bool _copyLinear;
|
||||
|
||||
private byte[] Buffer;
|
||||
private byte[] _buffer;
|
||||
|
||||
public NvGpuEngineP2mf(NvGpu Gpu)
|
||||
public NvGpuEngineP2mf(NvGpu gpu)
|
||||
{
|
||||
this.Gpu = Gpu;
|
||||
_gpu = gpu;
|
||||
|
||||
Registers = new int[0x80];
|
||||
|
||||
Methods = new Dictionary<int, NvGpuMethod>();
|
||||
_methods = new Dictionary<int, NvGpuMethod>();
|
||||
|
||||
void AddMethod(int Meth, int Count, int Stride, NvGpuMethod Method)
|
||||
void AddMethod(int meth, int count, int stride, NvGpuMethod method)
|
||||
{
|
||||
while (Count-- > 0)
|
||||
while (count-- > 0)
|
||||
{
|
||||
Methods.Add(Meth, Method);
|
||||
_methods.Add(meth, method);
|
||||
|
||||
Meth += Stride;
|
||||
meth += stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,115 +50,115 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
AddMethod(0x6d, 1, 1, PushData);
|
||||
}
|
||||
|
||||
public void CallMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
||||
public void CallMethod(NvGpuVmm vmm, GpuMethodCall methCall)
|
||||
{
|
||||
if (Methods.TryGetValue(MethCall.Method, out NvGpuMethod Method))
|
||||
if (_methods.TryGetValue(methCall.Method, out NvGpuMethod method))
|
||||
{
|
||||
Method(Vmm, MethCall);
|
||||
method(vmm, methCall);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteRegister(MethCall);
|
||||
WriteRegister(methCall);
|
||||
}
|
||||
}
|
||||
|
||||
private void Execute(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
||||
private void Execute(NvGpuVmm vmm, GpuMethodCall methCall)
|
||||
{
|
||||
//TODO: Some registers and copy modes are still not implemented.
|
||||
int Control = MethCall.Argument;
|
||||
int control = methCall.Argument;
|
||||
|
||||
long DstAddress = MakeInt64From2xInt32(NvGpuEngineP2mfReg.DstAddress);
|
||||
long dstAddress = MakeInt64From2xInt32(NvGpuEngineP2mfReg.DstAddress);
|
||||
|
||||
int DstPitch = ReadRegister(NvGpuEngineP2mfReg.DstPitch);
|
||||
int DstBlkDim = ReadRegister(NvGpuEngineP2mfReg.DstBlockDim);
|
||||
int dstPitch = ReadRegister(NvGpuEngineP2mfReg.DstPitch);
|
||||
int dstBlkDim = ReadRegister(NvGpuEngineP2mfReg.DstBlockDim);
|
||||
|
||||
int DstX = ReadRegister(NvGpuEngineP2mfReg.DstX);
|
||||
int DstY = ReadRegister(NvGpuEngineP2mfReg.DstY);
|
||||
int dstX = ReadRegister(NvGpuEngineP2mfReg.DstX);
|
||||
int dstY = ReadRegister(NvGpuEngineP2mfReg.DstY);
|
||||
|
||||
int DstWidth = ReadRegister(NvGpuEngineP2mfReg.DstWidth);
|
||||
int DstHeight = ReadRegister(NvGpuEngineP2mfReg.DstHeight);
|
||||
int dstWidth = ReadRegister(NvGpuEngineP2mfReg.DstWidth);
|
||||
int dstHeight = ReadRegister(NvGpuEngineP2mfReg.DstHeight);
|
||||
|
||||
int LineLengthIn = ReadRegister(NvGpuEngineP2mfReg.LineLengthIn);
|
||||
int LineCount = ReadRegister(NvGpuEngineP2mfReg.LineCount);
|
||||
int lineLengthIn = ReadRegister(NvGpuEngineP2mfReg.LineLengthIn);
|
||||
int lineCount = ReadRegister(NvGpuEngineP2mfReg.LineCount);
|
||||
|
||||
CopyLinear = (Control & 1) != 0;
|
||||
_copyLinear = (control & 1) != 0;
|
||||
|
||||
CopyGobBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf);
|
||||
_copyGobBlockHeight = 1 << ((dstBlkDim >> 4) & 0xf);
|
||||
|
||||
CopyStartX = DstX;
|
||||
CopyStartY = DstY;
|
||||
_copyStartX = dstX;
|
||||
_copyStartY = dstY;
|
||||
|
||||
CopyWidth = DstWidth;
|
||||
CopyHeight = DstHeight;
|
||||
_copyWidth = dstWidth;
|
||||
_copyHeight = dstHeight;
|
||||
|
||||
CopyAddress = DstAddress;
|
||||
_copyAddress = dstAddress;
|
||||
|
||||
CopyOffset = 0;
|
||||
CopySize = LineLengthIn * LineCount;
|
||||
_copyOffset = 0;
|
||||
_copySize = lineLengthIn * lineCount;
|
||||
|
||||
Buffer = new byte[CopySize];
|
||||
_buffer = new byte[_copySize];
|
||||
}
|
||||
|
||||
private void PushData(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
||||
private void PushData(NvGpuVmm vmm, GpuMethodCall methCall)
|
||||
{
|
||||
if (Buffer == null)
|
||||
if (_buffer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int Shift = 0; Shift < 32 && CopyOffset < CopySize; Shift += 8, CopyOffset++)
|
||||
for (int shift = 0; shift < 32 && _copyOffset < _copySize; shift += 8, _copyOffset++)
|
||||
{
|
||||
Buffer[CopyOffset] = (byte)(MethCall.Argument >> Shift);
|
||||
_buffer[_copyOffset] = (byte)(methCall.Argument >> shift);
|
||||
}
|
||||
|
||||
if (MethCall.IsLastCall)
|
||||
if (methCall.IsLastCall)
|
||||
{
|
||||
if (CopyLinear)
|
||||
if (_copyLinear)
|
||||
{
|
||||
Vmm.WriteBytes(CopyAddress, Buffer);
|
||||
vmm.WriteBytes(_copyAddress, _buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockLinearSwizzle Swizzle = new BlockLinearSwizzle(
|
||||
CopyWidth,
|
||||
CopyHeight, 1,
|
||||
CopyGobBlockHeight, 1, 1);
|
||||
BlockLinearSwizzle swizzle = new BlockLinearSwizzle(
|
||||
_copyWidth,
|
||||
_copyHeight, 1,
|
||||
_copyGobBlockHeight, 1, 1);
|
||||
|
||||
int SrcOffset = 0;
|
||||
int srcOffset = 0;
|
||||
|
||||
for (int Y = CopyStartY; Y < CopyHeight && SrcOffset < CopySize; Y++)
|
||||
for (int X = CopyStartX; X < CopyWidth && SrcOffset < CopySize; X++)
|
||||
for (int y = _copyStartY; y < _copyHeight && srcOffset < _copySize; y++)
|
||||
for (int x = _copyStartX; x < _copyWidth && srcOffset < _copySize; x++)
|
||||
{
|
||||
int DstOffset = Swizzle.GetSwizzleOffset(X, Y, 0);
|
||||
int dstOffset = swizzle.GetSwizzleOffset(x, y, 0);
|
||||
|
||||
Vmm.WriteByte(CopyAddress + DstOffset, Buffer[SrcOffset++]);
|
||||
vmm.WriteByte(_copyAddress + dstOffset, _buffer[srcOffset++]);
|
||||
}
|
||||
}
|
||||
|
||||
Buffer = null;
|
||||
_buffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private long MakeInt64From2xInt32(NvGpuEngineP2mfReg Reg)
|
||||
private long MakeInt64From2xInt32(NvGpuEngineP2mfReg reg)
|
||||
{
|
||||
return
|
||||
(long)Registers[(int)Reg + 0] << 32 |
|
||||
(uint)Registers[(int)Reg + 1];
|
||||
(long)Registers[(int)reg + 0] << 32 |
|
||||
(uint)Registers[(int)reg + 1];
|
||||
}
|
||||
|
||||
private void WriteRegister(GpuMethodCall MethCall)
|
||||
private void WriteRegister(GpuMethodCall methCall)
|
||||
{
|
||||
Registers[MethCall.Method] = MethCall.Argument;
|
||||
Registers[methCall.Method] = methCall.Argument;
|
||||
}
|
||||
|
||||
private int ReadRegister(NvGpuEngineP2mfReg Reg)
|
||||
private int ReadRegister(NvGpuEngineP2mfReg reg)
|
||||
{
|
||||
return Registers[(int)Reg];
|
||||
return Registers[(int)reg];
|
||||
}
|
||||
|
||||
private void WriteRegister(NvGpuEngineP2mfReg Reg, int Value)
|
||||
private void WriteRegister(NvGpuEngineP2mfReg reg, int value)
|
||||
{
|
||||
Registers[(int)Reg] = Value;
|
||||
Registers[(int)reg] = value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,166 +11,166 @@ namespace Ryujinx.Graphics.Graphics3d
|
|||
//a guess here and use 256kb as the size. Increase if needed.
|
||||
private const int MmeWords = 256 * 256;
|
||||
|
||||
private NvGpu Gpu;
|
||||
private NvGpu _gpu;
|
||||
|
||||
private NvGpuEngine[] SubChannels;
|
||||
private NvGpuEngine[] _subChannels;
|
||||
|
||||
private struct CachedMacro
|
||||
{
|
||||
public int Position { get; private set; }
|
||||
|
||||
private bool ExecutionPending;
|
||||
private int Argument;
|
||||
private bool _executionPending;
|
||||
private int _argument;
|
||||
|
||||
private MacroInterpreter Interpreter;
|
||||
private MacroInterpreter _interpreter;
|
||||
|
||||
public CachedMacro(NvGpuFifo PFifo, INvGpuEngine Engine, int Position)
|
||||
public CachedMacro(NvGpuFifo pFifo, INvGpuEngine engine, int position)
|
||||
{
|
||||
this.Position = Position;
|
||||
Position = position;
|
||||
|
||||
ExecutionPending = false;
|
||||
Argument = 0;
|
||||
_executionPending = false;
|
||||
_argument = 0;
|
||||
|
||||
Interpreter = new MacroInterpreter(PFifo, Engine);
|
||||
_interpreter = new MacroInterpreter(pFifo, engine);
|
||||
}
|
||||
|
||||
public void StartExecution(int Argument)
|
||||
public void StartExecution(int argument)
|
||||
{
|
||||
this.Argument = Argument;
|
||||
_argument = argument;
|
||||
|
||||
ExecutionPending = true;
|
||||
_executionPending = true;
|
||||
}
|
||||
|
||||
public void Execute(NvGpuVmm Vmm, int[] Mme)
|
||||
public void Execute(NvGpuVmm vmm, int[] mme)
|
||||
{
|
||||
if (ExecutionPending)
|
||||
if (_executionPending)
|
||||
{
|
||||
ExecutionPending = false;
|
||||
_executionPending = false;
|
||||
|
||||
Interpreter?.Execute(Vmm, Mme, Position, Argument);
|
||||
_interpreter?.Execute(vmm, mme, Position, _argument);
|
||||
}
|
||||
}
|
||||
|
||||
public void PushArgument(int Argument)
|
||||
public void PushArgument(int argument)
|
||||
{
|
||||
Interpreter?.Fifo.Enqueue(Argument);
|
||||
_interpreter?.Fifo.Enqueue(argument);
|
||||
}
|
||||
}
|
||||
|
||||
private int CurrMacroPosition;
|
||||
private int CurrMacroBindIndex;
|
||||
private int _currMacroPosition;
|
||||
private int _currMacroBindIndex;
|
||||
|
||||
private CachedMacro[] Macros;
|
||||
private CachedMacro[] _macros;
|
||||
|
||||
private int[] Mme;
|
||||
private int[] _mme;
|
||||
|
||||
public NvGpuFifo(NvGpu Gpu)
|
||||
public NvGpuFifo(NvGpu gpu)
|
||||
{
|
||||
this.Gpu = Gpu;
|
||||
_gpu = gpu;
|
||||
|
||||
SubChannels = new NvGpuEngine[8];
|
||||
_subChannels = new NvGpuEngine[8];
|
||||
|
||||
Macros = new CachedMacro[MacrosCount];
|
||||
_macros = new CachedMacro[MacrosCount];
|
||||
|
||||
Mme = new int[MmeWords];
|
||||
_mme = new int[MmeWords];
|
||||
}
|
||||
|
||||
public void CallMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
||||
public void CallMethod(NvGpuVmm vmm, GpuMethodCall methCall)
|
||||
{
|
||||
if ((NvGpuFifoMeth)MethCall.Method == NvGpuFifoMeth.BindChannel)
|
||||
if ((NvGpuFifoMeth)methCall.Method == NvGpuFifoMeth.BindChannel)
|
||||
{
|
||||
NvGpuEngine Engine = (NvGpuEngine)MethCall.Argument;
|
||||
NvGpuEngine engine = (NvGpuEngine)methCall.Argument;
|
||||
|
||||
SubChannels[MethCall.SubChannel] = Engine;
|
||||
_subChannels[methCall.SubChannel] = engine;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (SubChannels[MethCall.SubChannel])
|
||||
switch (_subChannels[methCall.SubChannel])
|
||||
{
|
||||
case NvGpuEngine._2d: Call2dMethod (Vmm, MethCall); break;
|
||||
case NvGpuEngine._3d: Call3dMethod (Vmm, MethCall); break;
|
||||
case NvGpuEngine.P2mf: CallP2mfMethod(Vmm, MethCall); break;
|
||||
case NvGpuEngine.M2mf: CallM2mfMethod(Vmm, MethCall); break;
|
||||
case NvGpuEngine._2d: Call2dMethod (vmm, methCall); break;
|
||||
case NvGpuEngine._3d: Call3dMethod (vmm, methCall); break;
|
||||
case NvGpuEngine.P2mf: CallP2mfMethod(vmm, methCall); break;
|
||||
case NvGpuEngine.M2mf: CallM2mfMethod(vmm, methCall); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Call2dMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
||||
private void Call2dMethod(NvGpuVmm vmm, GpuMethodCall methCall)
|
||||
{
|
||||
Gpu.Engine2d.CallMethod(Vmm, MethCall);
|
||||
_gpu.Engine2d.CallMethod(vmm, methCall);
|
||||
}
|
||||
|
||||
private void Call3dMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
||||
private void Call3dMethod(NvGpuVmm vmm, GpuMethodCall methCall)
|
||||
{
|
||||
if (MethCall.Method < 0x80)
|
||||
if (methCall.Method < 0x80)
|
||||
{
|
||||
switch ((NvGpuFifoMeth)MethCall.Method)
|
||||
switch ((NvGpuFifoMeth)methCall.Method)
|
||||
{
|
||||
case NvGpuFifoMeth.SetMacroUploadAddress:
|
||||
{
|
||||
CurrMacroPosition = MethCall.Argument;
|
||||
_currMacroPosition = methCall.Argument;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NvGpuFifoMeth.SendMacroCodeData:
|
||||
{
|
||||
Mme[CurrMacroPosition++] = MethCall.Argument;
|
||||
_mme[_currMacroPosition++] = methCall.Argument;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NvGpuFifoMeth.SetMacroBindingIndex:
|
||||
{
|
||||
CurrMacroBindIndex = MethCall.Argument;
|
||||
_currMacroBindIndex = methCall.Argument;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NvGpuFifoMeth.BindMacro:
|
||||
{
|
||||
int Position = MethCall.Argument;
|
||||
int position = methCall.Argument;
|
||||
|
||||
Macros[CurrMacroBindIndex] = new CachedMacro(this, Gpu.Engine3d, Position);
|
||||
_macros[_currMacroBindIndex] = new CachedMacro(this, _gpu.Engine3d, position);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: CallP2mfMethod(Vmm, MethCall); break;
|
||||
default: CallP2mfMethod(vmm, methCall); break;
|
||||
}
|
||||
}
|
||||
else if (MethCall.Method < 0xe00)
|
||||
else if (methCall.Method < 0xe00)
|
||||
{
|
||||
Gpu.Engine3d.CallMethod(Vmm, MethCall);
|
||||
_gpu.Engine3d.CallMethod(vmm, methCall);
|
||||
}
|
||||
else
|
||||
{
|
||||
int MacroIndex = (MethCall.Method >> 1) & MacroIndexMask;
|
||||
int macroIndex = (methCall.Method >> 1) & MacroIndexMask;
|
||||
|
||||
if ((MethCall.Method & 1) != 0)
|
||||
if ((methCall.Method & 1) != 0)
|
||||
{
|
||||
Macros[MacroIndex].PushArgument(MethCall.Argument);
|
||||
_macros[macroIndex].PushArgument(methCall.Argument);
|
||||
}
|
||||
else
|
||||
{
|
||||
Macros[MacroIndex].StartExecution(MethCall.Argument);
|
||||
_macros[macroIndex].StartExecution(methCall.Argument);
|
||||
}
|
||||
|
||||
if (MethCall.IsLastCall)
|
||||
if (methCall.IsLastCall)
|
||||
{
|
||||
Macros[MacroIndex].Execute(Vmm, Mme);
|
||||
_macros[macroIndex].Execute(vmm, _mme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CallP2mfMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
||||
private void CallP2mfMethod(NvGpuVmm vmm, GpuMethodCall methCall)
|
||||
{
|
||||
Gpu.EngineP2mf.CallMethod(Vmm, MethCall);
|
||||
_gpu.EngineP2mf.CallMethod(vmm, methCall);
|
||||
}
|
||||
|
||||
private void CallM2mfMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
||||
private void CallM2mfMethod(NvGpuVmm vmm, GpuMethodCall methCall)
|
||||
{
|
||||
Gpu.EngineM2mf.CallMethod(Vmm, MethCall);
|
||||
_gpu.EngineM2mf.CallMethod(vmm, methCall);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,5 +2,5 @@ using Ryujinx.Graphics.Memory;
|
|||
|
||||
namespace Ryujinx.Graphics.Graphics3d
|
||||
{
|
||||
delegate void NvGpuMethod(NvGpuVmm Vmm, GpuMethodCall MethCall);
|
||||
delegate void NvGpuMethod(NvGpuVmm vmm, GpuMethodCall methCall);
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,138 +0,0 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Graphics.Texture
|
||||
{
|
||||
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];
|
||||
|
||||
public ASTCPixel(short _A, short _R, short _G, short _B)
|
||||
{
|
||||
A = _A;
|
||||
R = _R;
|
||||
G = _G;
|
||||
B = _B;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
BitDepth[i] = 8;
|
||||
}
|
||||
|
||||
public void ClampByte()
|
||||
{
|
||||
R = Math.Min(Math.Max(R, (short)0), (short)255);
|
||||
G = Math.Min(Math.Max(G, (short)0), (short)255);
|
||||
B = Math.Min(Math.Max(B, (short)0), (short)255);
|
||||
A = Math.Min(Math.Max(A, (short)0), (short)255);
|
||||
}
|
||||
|
||||
public short GetComponent(int Index)
|
||||
{
|
||||
switch(Index)
|
||||
{
|
||||
case 0: return A;
|
||||
case 1: return R;
|
||||
case 2: return G;
|
||||
case 3: return B;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void SetComponent(int Index, int Value)
|
||||
{
|
||||
switch (Index)
|
||||
{
|
||||
case 0:
|
||||
A = (short)Value;
|
||||
break;
|
||||
case 1:
|
||||
R = (short)Value;
|
||||
break;
|
||||
case 2:
|
||||
G = (short)Value;
|
||||
break;
|
||||
case 3:
|
||||
B = (short)Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeBitDepth(byte[] Depth)
|
||||
{
|
||||
for(int i = 0; i< 4; i++)
|
||||
{
|
||||
int Value = ChangeBitDepth(GetComponent(i), BitDepth[i], Depth[i]);
|
||||
|
||||
SetComponent(i, Value);
|
||||
BitDepth[i] = Depth[i];
|
||||
}
|
||||
}
|
||||
|
||||
short ChangeBitDepth(short Value, byte OldDepth, byte NewDepth)
|
||||
{
|
||||
Debug.Assert(NewDepth <= 8);
|
||||
Debug.Assert(OldDepth <= 8);
|
||||
|
||||
if (OldDepth == NewDepth)
|
||||
{
|
||||
// Do nothing
|
||||
return Value;
|
||||
}
|
||||
else if (OldDepth == 0 && NewDepth != 0)
|
||||
{
|
||||
return (short)((1 << NewDepth) - 1);
|
||||
}
|
||||
else if (NewDepth > OldDepth)
|
||||
{
|
||||
return (short)BitArrayStream.Replicate(Value, OldDepth, NewDepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
// oldDepth > newDepth
|
||||
if (NewDepth == 0)
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte BitsWasted = (byte)(OldDepth - NewDepth);
|
||||
short TempValue = Value;
|
||||
|
||||
TempValue = (short)((TempValue + (1 << (BitsWasted - 1))) >> BitsWasted);
|
||||
TempValue = Math.Min(Math.Max((short)0, TempValue), (short)((1 << NewDepth) - 1));
|
||||
|
||||
return (byte)(TempValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Pack()
|
||||
{
|
||||
ASTCPixel NewPixel = new ASTCPixel(A, R, G, B);
|
||||
byte[] eightBitDepth = { 8, 8, 8, 8 };
|
||||
|
||||
NewPixel.ChangeBitDepth(eightBitDepth);
|
||||
|
||||
return (byte)NewPixel.A << 24 |
|
||||
(byte)NewPixel.B << 16 |
|
||||
(byte)NewPixel.G << 8 |
|
||||
(byte)NewPixel.R << 0;
|
||||
}
|
||||
|
||||
// Adds more precision to the blue channel as described
|
||||
// in C.2.14
|
||||
public static ASTCPixel BlueContract(int a, int r, int g, int b)
|
||||
{
|
||||
return new ASTCPixel((short)(a),
|
||||
(short)((r + b) >> 1),
|
||||
(short)((g + b) >> 1),
|
||||
(short)(b));
|
||||
}
|
||||
}
|
||||
}
|
1385
Ryujinx.Graphics/Graphics3d/Texture/AstcDecoder.cs
Normal file
1385
Ryujinx.Graphics/Graphics3d/Texture/AstcDecoder.cs
Normal file
File diff suppressed because it is too large
Load diff
138
Ryujinx.Graphics/Graphics3d/Texture/AstcPixel.cs
Normal file
138
Ryujinx.Graphics/Graphics3d/Texture/AstcPixel.cs
Normal file
|
@ -0,0 +1,138 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Graphics.Texture
|
||||
{
|
||||
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];
|
||||
|
||||
public AstcPixel(short a, short r, short g, short b)
|
||||
{
|
||||
A = a;
|
||||
R = r;
|
||||
G = g;
|
||||
B = b;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
_bitDepth[i] = 8;
|
||||
}
|
||||
|
||||
public void ClampByte()
|
||||
{
|
||||
R = Math.Min(Math.Max(R, (short)0), (short)255);
|
||||
G = Math.Min(Math.Max(G, (short)0), (short)255);
|
||||
B = Math.Min(Math.Max(B, (short)0), (short)255);
|
||||
A = Math.Min(Math.Max(A, (short)0), (short)255);
|
||||
}
|
||||
|
||||
public short GetComponent(int index)
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
case 0: return A;
|
||||
case 1: return R;
|
||||
case 2: return G;
|
||||
case 3: return B;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void SetComponent(int index, int value)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
A = (short)value;
|
||||
break;
|
||||
case 1:
|
||||
R = (short)value;
|
||||
break;
|
||||
case 2:
|
||||
G = (short)value;
|
||||
break;
|
||||
case 3:
|
||||
B = (short)value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeBitDepth(byte[] depth)
|
||||
{
|
||||
for(int i = 0; i< 4; i++)
|
||||
{
|
||||
int value = ChangeBitDepth(GetComponent(i), _bitDepth[i], depth[i]);
|
||||
|
||||
SetComponent(i, value);
|
||||
_bitDepth[i] = depth[i];
|
||||
}
|
||||
}
|
||||
|
||||
short ChangeBitDepth(short value, byte oldDepth, byte newDepth)
|
||||
{
|
||||
Debug.Assert(newDepth <= 8);
|
||||
Debug.Assert(oldDepth <= 8);
|
||||
|
||||
if (oldDepth == newDepth)
|
||||
{
|
||||
// Do nothing
|
||||
return value;
|
||||
}
|
||||
else if (oldDepth == 0 && newDepth != 0)
|
||||
{
|
||||
return (short)((1 << newDepth) - 1);
|
||||
}
|
||||
else if (newDepth > oldDepth)
|
||||
{
|
||||
return (short)BitArrayStream.Replicate(value, oldDepth, newDepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
// oldDepth > newDepth
|
||||
if (newDepth == 0)
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte bitsWasted = (byte)(oldDepth - newDepth);
|
||||
short tempValue = value;
|
||||
|
||||
tempValue = (short)((tempValue + (1 << (bitsWasted - 1))) >> bitsWasted);
|
||||
tempValue = Math.Min(Math.Max((short)0, tempValue), (short)((1 << newDepth) - 1));
|
||||
|
||||
return (byte)(tempValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Pack()
|
||||
{
|
||||
AstcPixel newPixel = new AstcPixel(A, R, G, B);
|
||||
byte[] eightBitDepth = { 8, 8, 8, 8 };
|
||||
|
||||
newPixel.ChangeBitDepth(eightBitDepth);
|
||||
|
||||
return (byte)newPixel.A << 24 |
|
||||
(byte)newPixel.B << 16 |
|
||||
(byte)newPixel.G << 8 |
|
||||
(byte)newPixel.R << 0;
|
||||
}
|
||||
|
||||
// Adds more precision to the blue channel as described
|
||||
// in C.2.14
|
||||
public static AstcPixel BlueContract(int a, int r, int g, int b)
|
||||
{
|
||||
return new AstcPixel((short)(a),
|
||||
(short)((r + b) >> 1),
|
||||
(short)((g + b) >> 1),
|
||||
(short)(b));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
Height = gobBlockHeight;
|
||||
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;
|
||||
RobSize = robSize;
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
using ChocolArm64.Memory;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.Gal;
|
||||
using Ryujinx.Graphics.Memory;
|
||||
using System;
|
||||
|
@ -29,13 +28,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;
|
||||
BytesPerPixel = bytesPerPixel;
|
||||
BlockWidth = blockWidth;
|
||||
BlockHeight = blockHeight;
|
||||
BlockDepth = blockDepth;
|
||||
Target = target;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,26 +45,26 @@ 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 },
|
||||
{ GalTextureFormat.RGBA16, GalImageFormat.RGBA16 | Snorm | Unorm | Sint | Uint | Float },
|
||||
{ GalTextureFormat.RG32, GalImageFormat.RG32 | Sint | Uint | Float },
|
||||
{ GalTextureFormat.RGBA8, GalImageFormat.RGBA8 | Snorm | Unorm | Sint | Uint | Srgb },
|
||||
{ GalTextureFormat.RGB10A2, GalImageFormat.RGB10A2 | Snorm | Unorm | Sint | Uint },
|
||||
{ GalTextureFormat.RG8, GalImageFormat.RG8 | Snorm | Unorm | Sint | Uint },
|
||||
{ GalTextureFormat.Rgba32, GalImageFormat.Rgba32 | Sint | Uint | Float },
|
||||
{ GalTextureFormat.Rgba16, GalImageFormat.Rgba16 | Snorm | Unorm | Sint | Uint | Float },
|
||||
{ GalTextureFormat.Rg32, GalImageFormat.Rg32 | Sint | Uint | Float },
|
||||
{ GalTextureFormat.Rgba8, GalImageFormat.Rgba8 | Snorm | Unorm | Sint | Uint | Srgb },
|
||||
{ GalTextureFormat.Rgb10A2, GalImageFormat.Rgb10A2 | Snorm | Unorm | Sint | Uint },
|
||||
{ GalTextureFormat.Rg8, GalImageFormat.Rg8 | Snorm | Unorm | Sint | Uint },
|
||||
{ GalTextureFormat.R16, GalImageFormat.R16 | Snorm | Unorm | Sint | Uint | Float },
|
||||
{ GalTextureFormat.R8, GalImageFormat.R8 | Snorm | Unorm | Sint | Uint },
|
||||
{ GalTextureFormat.RG16, GalImageFormat.RG16 | Snorm | Unorm | Sint | Float },
|
||||
{ GalTextureFormat.Rg16, GalImageFormat.Rg16 | Snorm | Unorm | Sint | Float },
|
||||
{ GalTextureFormat.R32, GalImageFormat.R32 | Sint | Uint | Float },
|
||||
{ GalTextureFormat.RGBA4, GalImageFormat.RGBA4 | Unorm },
|
||||
{ GalTextureFormat.RGB5A1, GalImageFormat.RGB5A1 | Unorm },
|
||||
{ GalTextureFormat.RGB565, GalImageFormat.RGB565 | Unorm },
|
||||
{ GalTextureFormat.Rgba4, GalImageFormat.Rgba4 | Unorm },
|
||||
{ GalTextureFormat.Rgb5A1, GalImageFormat.Rgb5A1 | Unorm },
|
||||
{ GalTextureFormat.Rgb565, GalImageFormat.Rgb565 | Unorm },
|
||||
{ GalTextureFormat.R11G11B10F, GalImageFormat.R11G11B10 | Float },
|
||||
{ GalTextureFormat.D24S8, GalImageFormat.D24S8 | Unorm | Uint },
|
||||
{ GalTextureFormat.D32F, GalImageFormat.D32 | Float },
|
||||
{ GalTextureFormat.D32FX24S8, GalImageFormat.D32S8 | Float },
|
||||
{ GalTextureFormat.D32Fx24S8, GalImageFormat.D32S8 | Float },
|
||||
{ GalTextureFormat.D16, GalImageFormat.D16 | Unorm },
|
||||
|
||||
//Compressed formats
|
||||
|
@ -93,27 +92,27 @@ 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) },
|
||||
{ GalImageFormat.RGBA16, new ImageDescriptor(8, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.RG32, new ImageDescriptor(8, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.RGBX8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.RGBA8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BGRA8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.RGB10A2, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Rgba32, new ImageDescriptor(16, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Rgba16, new ImageDescriptor(8, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Rg32, new ImageDescriptor(8, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Rgbx8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Rgba8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Bgra8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Rgb10A2, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.R32, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.RGBA4, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Rgba4, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BptcSfloat, new ImageDescriptor(16, 4, 4, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BptcUfloat, new ImageDescriptor(16, 4, 4, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BGR5A1, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.RGB5A1, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.RGB565, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BGR565, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Bgr5A1, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Rgb5A1, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Rgb565, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Bgr565, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BptcUnorm, new ImageDescriptor(16, 4, 4, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.RG16, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.RG8, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Rg16, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.Rg8, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.R16, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.R8, new ImageDescriptor(1, 1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.R11G11B10, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||
|
@ -145,77 +144,77 @@ 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!");
|
||||
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;
|
||||
case GalSurfaceFormat.RGBA16Float: return GalImageFormat.RGBA16 | Float;
|
||||
case GalSurfaceFormat.RGBA16Unorm: return GalImageFormat.RGBA16 | Unorm;
|
||||
case GalSurfaceFormat.RG32Float: return GalImageFormat.RG32 | Float;
|
||||
case GalSurfaceFormat.RG32Sint: return GalImageFormat.RG32 | Sint;
|
||||
case GalSurfaceFormat.RG32Uint: return GalImageFormat.RG32 | Uint;
|
||||
case GalSurfaceFormat.BGRA8Unorm: return GalImageFormat.BGRA8 | Unorm;
|
||||
case GalSurfaceFormat.BGRA8Srgb: return GalImageFormat.BGRA8 | Srgb;
|
||||
case GalSurfaceFormat.RGB10A2Unorm: return GalImageFormat.RGB10A2 | Unorm;
|
||||
case GalSurfaceFormat.RGBA8Unorm: return GalImageFormat.RGBA8 | Unorm;
|
||||
case GalSurfaceFormat.RGBA8Srgb: return GalImageFormat.RGBA8 | Srgb;
|
||||
case GalSurfaceFormat.RGBA8Snorm: return GalImageFormat.RGBA8 | Snorm;
|
||||
case GalSurfaceFormat.RG16Snorm: return GalImageFormat.RG16 | Snorm;
|
||||
case GalSurfaceFormat.RG16Unorm: return GalImageFormat.RG16 | Unorm;
|
||||
case GalSurfaceFormat.RG16Sint: return GalImageFormat.RG16 | Sint;
|
||||
case GalSurfaceFormat.RG16Float: return GalImageFormat.RG16 | Float;
|
||||
case GalSurfaceFormat.Rgba32Float: return GalImageFormat.Rgba32 | Float;
|
||||
case GalSurfaceFormat.Rgba32Uint: return GalImageFormat.Rgba32 | Uint;
|
||||
case GalSurfaceFormat.Rgba16Float: return GalImageFormat.Rgba16 | Float;
|
||||
case GalSurfaceFormat.Rgba16Unorm: return GalImageFormat.Rgba16 | Unorm;
|
||||
case GalSurfaceFormat.Rg32Float: return GalImageFormat.Rg32 | Float;
|
||||
case GalSurfaceFormat.Rg32Sint: return GalImageFormat.Rg32 | Sint;
|
||||
case GalSurfaceFormat.Rg32Uint: return GalImageFormat.Rg32 | Uint;
|
||||
case GalSurfaceFormat.Bgra8Unorm: return GalImageFormat.Bgra8 | Unorm;
|
||||
case GalSurfaceFormat.Bgra8Srgb: return GalImageFormat.Bgra8 | Srgb;
|
||||
case GalSurfaceFormat.Rgb10A2Unorm: return GalImageFormat.Rgb10A2 | Unorm;
|
||||
case GalSurfaceFormat.Rgba8Unorm: return GalImageFormat.Rgba8 | Unorm;
|
||||
case GalSurfaceFormat.Rgba8Srgb: return GalImageFormat.Rgba8 | Srgb;
|
||||
case GalSurfaceFormat.Rgba8Snorm: return GalImageFormat.Rgba8 | Snorm;
|
||||
case GalSurfaceFormat.Rg16Snorm: return GalImageFormat.Rg16 | Snorm;
|
||||
case GalSurfaceFormat.Rg16Unorm: return GalImageFormat.Rg16 | Unorm;
|
||||
case GalSurfaceFormat.Rg16Sint: return GalImageFormat.Rg16 | Sint;
|
||||
case GalSurfaceFormat.Rg16Float: return GalImageFormat.Rg16 | Float;
|
||||
case GalSurfaceFormat.R11G11B10Float: return GalImageFormat.R11G11B10 | Float;
|
||||
case GalSurfaceFormat.R32Float: return GalImageFormat.R32 | Float;
|
||||
case GalSurfaceFormat.R32Uint: return GalImageFormat.R32 | Uint;
|
||||
case GalSurfaceFormat.RG8Unorm: return GalImageFormat.RG8 | Unorm;
|
||||
case GalSurfaceFormat.RG8Snorm: return GalImageFormat.RG8 | Snorm;
|
||||
case GalSurfaceFormat.Rg8Unorm: return GalImageFormat.Rg8 | Unorm;
|
||||
case GalSurfaceFormat.Rg8Snorm: return GalImageFormat.Rg8 | Snorm;
|
||||
case GalSurfaceFormat.R16Float: return GalImageFormat.R16 | Float;
|
||||
case GalSurfaceFormat.R16Unorm: return GalImageFormat.R16 | Unorm;
|
||||
case GalSurfaceFormat.R16Uint: return GalImageFormat.R16 | Uint;
|
||||
case GalSurfaceFormat.R8Unorm: return GalImageFormat.R8 | Unorm;
|
||||
case GalSurfaceFormat.R8Uint: return GalImageFormat.R8 | Uint;
|
||||
case GalSurfaceFormat.B5G6R5Unorm: return GalImageFormat.RGB565 | Unorm;
|
||||
case GalSurfaceFormat.BGR5A1Unorm: return GalImageFormat.BGR5A1 | Unorm;
|
||||
case GalSurfaceFormat.RGBX8Unorm: return GalImageFormat.RGBX8 | Unorm;
|
||||
case GalSurfaceFormat.B5G6R5Unorm: return GalImageFormat.Rgb565 | Unorm;
|
||||
case GalSurfaceFormat.Bgr5A1Unorm: return GalImageFormat.Bgr5A1 | 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.S8D24Unorm: return GalImageFormat.D24S8 | Unorm;
|
||||
|
@ -225,268 +224,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 = 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) = 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 +493,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 +519,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 +536,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 +554,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[] q = new int[3];
|
||||
int Q;
|
||||
int[] qa = new int[3];
|
||||
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)
|
||||
{
|
||||
q[0] = q[1] = 4;
|
||||
q[2] = (Qb.ReadBit(0) << 2) | ((Qb.ReadBit(4) & ~Qb.ReadBit(0)) << 1) | (Qb.ReadBit(3) & ~Qb.ReadBit(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));
|
||||
}
|
||||
else
|
||||
{
|
||||
int C = 0;
|
||||
if (Qb.ReadBits(1, 2) == 3)
|
||||
int c = 0;
|
||||
if (qb.ReadBits(1, 2) == 3)
|
||||
{
|
||||
q[2] = 4;
|
||||
C = (Qb.ReadBits(3, 4) << 3) | ((~Qb.ReadBits(5, 6) & 3) << 1) | Qb.ReadBit(0);
|
||||
qa[2] = 4;
|
||||
c = (qb.ReadBits(3, 4) << 3) | ((~qb.ReadBits(5, 6) & 3) << 1) | qb.ReadBit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
q[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)
|
||||
{
|
||||
q[1] = 4;
|
||||
q[0] = Cb.ReadBits(3, 4);
|
||||
qa[1] = 4;
|
||||
qa[0] = cb.ReadBits(3, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
q[1] = Cb.ReadBits(3, 4);
|
||||
q[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 = q[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;
|
||||
_pitch = pitch;
|
||||
_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
Add a link
Reference in a new issue