diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-09-08 14:51:50 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-09-08 14:51:50 -0300 |
| commit | ce1d5be212e6f71a7ca32c3bd7b48e32d9f51b9a (patch) | |
| tree | 759fe422127ce08c545d4616ccc9691f668032ec /Ryujinx.HLE/Gpu/Engines | |
| parent | a0c78f792012cdea060444d7cb6a36dbabb04d52 (diff) | |
Move GPU emulation from Ryujinx.HLE to Ryujinx.Graphics and misc changes (#402)
* Move GPU LLE emulation from HLE to Graphics
* Graphics: Move Gal/Texture to Texture
* Remove Engines/ directory and namespace
* Use tables for image formats
* Abstract OpCode decoding
* Simplify image table
* Do not leak Read* symbols in TextureReader
* Fixups
* Rename IGalFrameBuffer -> IGalRenderTarget
* Remove MaxBpp hardcoded value
* Change yet again texture data and add G8R8 flipping
* Rename GalFrameBufferFormat to GalSurfaceFormat
* Unident EnsureSetup in ImageHandler
* Add IsCompressed
* Address some feedback
Diffstat (limited to 'Ryujinx.HLE/Gpu/Engines')
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/INvGpuEngine.cs | 11 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/MacroInterpreter.cs | 418 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngine.cs | 11 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs | 208 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngine2dReg.cs | 25 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs | 895 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs | 101 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngineDma.cs | 143 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngineDmaReg.cs | 22 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuFifo.cs | 198 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuFifoMeth.cs | 11 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuMethod.cs | 6 |
12 files changed, 0 insertions, 2049 deletions
diff --git a/Ryujinx.HLE/Gpu/Engines/INvGpuEngine.cs b/Ryujinx.HLE/Gpu/Engines/INvGpuEngine.cs deleted file mode 100644 index 068878a9..00000000 --- a/Ryujinx.HLE/Gpu/Engines/INvGpuEngine.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Ryujinx.HLE.Gpu.Memory; - -namespace Ryujinx.HLE.Gpu.Engines -{ - interface INvGpuEngine - { - int[] Registers { get; } - - void CallMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry); - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Engines/MacroInterpreter.cs b/Ryujinx.HLE/Gpu/Engines/MacroInterpreter.cs deleted file mode 100644 index 423e2021..00000000 --- a/Ryujinx.HLE/Gpu/Engines/MacroInterpreter.cs +++ /dev/null @@ -1,418 +0,0 @@ -using Ryujinx.HLE.Gpu.Memory; -using System; -using System.Collections.Generic; - -namespace Ryujinx.HLE.Gpu.Engines -{ - class MacroInterpreter - { - private enum AssignmentOperation - { - IgnoreAndFetch = 0, - Move = 1, - MoveAndSetMaddr = 2, - FetchAndSend = 3, - MoveAndSend = 4, - FetchAndSetMaddr = 5, - MoveAndSetMaddrThenFetchAndSend = 6, - MoveAndSetMaddrThenSendHigh = 7 - } - - private enum AluOperation - { - AluReg = 0, - AddImmediate = 1, - BitfieldReplace = 2, - BitfieldExtractLslImm = 3, - BitfieldExtractLslReg = 4, - ReadImmediate = 5 - } - - private enum AluRegOperation - { - Add = 0, - AddWithCarry = 1, - Subtract = 2, - SubtractWithBorrow = 3, - BitwiseExclusiveOr = 8, - BitwiseOr = 9, - BitwiseAnd = 10, - BitwiseAndNot = 11, - BitwiseNotAnd = 12 - } - - private NvGpuFifo PFifo; - private INvGpuEngine Engine; - - public Queue<int> Fifo { get; private set; } - - private int[] Gprs; - - private int MethAddr; - private int MethIncr; - - private bool Carry; - - private int OpCode; - - private int PipeOp; - - private int Pc; - - public MacroInterpreter(NvGpuFifo PFifo, INvGpuEngine Engine) - { - this.PFifo = PFifo; - this.Engine = Engine; - - Fifo = new Queue<int>(); - - Gprs = new int[8]; - } - - public void Execute(NvGpuVmm Vmm, int[] Mme, int Position, int Param) - { - Reset(); - - Gprs[1] = Param; - - Pc = Position; - - FetchOpCode(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); - } - - private void Reset() - { - for (int Index = 0; Index < Gprs.Length; Index++) - { - Gprs[Index] = 0; - } - - MethAddr = 0; - MethIncr = 0; - - Carry = false; - } - - private bool Step(NvGpuVmm Vmm, int[] Mme) - { - int BaseAddr = Pc - 1; - - FetchOpCode(Mme); - - if ((OpCode & 7) < 7) - { - //Operation produces a value. - AssignmentOperation AsgOp = (AssignmentOperation)((OpCode >> 4) & 7); - - int Result = GetAluResult(); - - switch (AsgOp) - { - //Fetch parameter and ignore result. - case AssignmentOperation.IgnoreAndFetch: - { - SetDstGpr(FetchParam()); - - break; - } - - //Move result. - case AssignmentOperation.Move: - { - SetDstGpr(Result); - - break; - } - - //Move result and use as Method Address. - case AssignmentOperation.MoveAndSetMaddr: - { - SetDstGpr(Result); - - SetMethAddr(Result); - - break; - } - - //Fetch parameter and send result. - case AssignmentOperation.FetchAndSend: - { - SetDstGpr(FetchParam()); - - Send(Vmm, Result); - - break; - } - - //Move and send result. - case AssignmentOperation.MoveAndSend: - { - SetDstGpr(Result); - - Send(Vmm, Result); - - break; - } - - //Fetch parameter and use result as Method Address. - case AssignmentOperation.FetchAndSetMaddr: - { - SetDstGpr(FetchParam()); - - SetMethAddr(Result); - - break; - } - - //Move result and use as Method Address, then fetch and send paramter. - case AssignmentOperation.MoveAndSetMaddrThenFetchAndSend: - { - SetDstGpr(Result); - - SetMethAddr(Result); - - Send(Vmm, FetchParam()); - - break; - } - - //Move result and use as Method Address, then send bits 17:12 of result. - case AssignmentOperation.MoveAndSetMaddrThenSendHigh: - { - SetDstGpr(Result); - - SetMethAddr(Result); - - Send(Vmm, (Result >> 12) & 0x3f); - - break; - } - } - } - else - { - //Branch. - bool OnNotZero = ((OpCode >> 4) & 1) != 0; - - bool Taken = OnNotZero - ? GetGprA() != 0 - : GetGprA() == 0; - - if (Taken) - { - Pc = BaseAddr + GetImm(); - - bool NoDelays = (OpCode & 0x20) != 0; - - if (NoDelays) - { - FetchOpCode(Mme); - } - - return true; - } - } - - bool Exit = (OpCode & 0x80) != 0; - - return !Exit; - } - - private void FetchOpCode(int[] Mme) - { - OpCode = PipeOp; - - PipeOp = Mme[Pc++]; - } - - private int GetAluResult() - { - AluOperation Op = (AluOperation)(OpCode & 7); - - switch (Op) - { - case AluOperation.AluReg: - { - AluRegOperation AluOp = (AluRegOperation)((OpCode >> 17) & 0x1f); - - return GetAluResult(AluOp, GetGprA(), GetGprB()); - } - - case AluOperation.AddImmediate: - { - return GetGprA() + GetImm(); - } - - case AluOperation.BitfieldReplace: - case AluOperation.BitfieldExtractLslImm: - case AluOperation.BitfieldExtractLslReg: - { - int BfSrcBit = (OpCode >> 17) & 0x1f; - int BfSize = (OpCode >> 22) & 0x1f; - int BfDstBit = (OpCode >> 27) & 0x1f; - - int BfMask = (1 << BfSize) - 1; - - int Dst = GetGprA(); - int Src = GetGprB(); - - switch (Op) - { - case AluOperation.BitfieldReplace: - { - Src = (int)((uint)Src >> BfSrcBit) & BfMask; - - Dst &= ~(BfMask << BfDstBit); - - Dst |= Src << BfDstBit; - - return Dst; - } - - case AluOperation.BitfieldExtractLslImm: - { - Src = (int)((uint)Src >> Dst) & BfMask; - - return Src << BfDstBit; - } - - case AluOperation.BitfieldExtractLslReg: - { - Src = (int)((uint)Src >> BfSrcBit) & BfMask; - - return Src << Dst; - } - } - - break; - } - - case AluOperation.ReadImmediate: - { - return Read(GetGprA() + GetImm()); - } - } - - throw new ArgumentException(nameof(OpCode)); - } - - private int GetAluResult(AluRegOperation AluOp, int A, int B) - { - switch (AluOp) - { - case AluRegOperation.Add: - { - ulong Result = (ulong)A + (ulong)B; - - Carry = Result > 0xffffffff; - - return (int)Result; - } - - case AluRegOperation.AddWithCarry: - { - ulong Result = (ulong)A + (ulong)B + (Carry ? 1UL : 0UL); - - Carry = Result > 0xffffffff; - - return (int)Result; - } - - case AluRegOperation.Subtract: - { - ulong Result = (ulong)A - (ulong)B; - - Carry = Result < 0x100000000; - - return (int)Result; - } - - case AluRegOperation.SubtractWithBorrow: - { - ulong Result = (ulong)A - (ulong)B - (Carry ? 0UL : 1UL); - - Carry = Result < 0x100000000; - - 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); - } - - throw new ArgumentOutOfRangeException(nameof(AluOp)); - } - - private int GetImm() - { - //Note: The immediate is signed, the sign-extension is intended here. - return OpCode >> 14; - } - - private void SetMethAddr(int Value) - { - MethAddr = (Value >> 0) & 0xfff; - MethIncr = (Value >> 12) & 0x3f; - } - - private void SetDstGpr(int Value) - { - Gprs[(OpCode >> 8) & 7] = Value; - } - - private int GetGprA() - { - return GetGprValue((OpCode >> 11) & 7); - } - - private int GetGprB() - { - return GetGprValue((OpCode >> 14) & 7); - } - - private int GetGprValue(int Index) - { - return Index != 0 ? Gprs[Index] : 0; - } - - private int FetchParam() - { - int Value; - - //If we don't have any parameters in the FIFO, - //keep running the PFIFO engine until it writes the parameters. - while (!Fifo.TryDequeue(out Value)) - { - if (!PFifo.Step()) - { - return 0; - } - } - - return Value; - } - - private int Read(int Reg) - { - return Engine.Registers[Reg]; - } - - private void Send(NvGpuVmm Vmm, int Value) - { - NvGpuPBEntry PBEntry = new NvGpuPBEntry(MethAddr, 0, Value); - - Engine.CallMethod(Vmm, PBEntry); - - MethAddr += MethIncr; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine.cs deleted file mode 100644 index f9d6342c..00000000 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.HLE.Gpu.Engines -{ - enum NvGpuEngine - { - _2d = 0x902d, - _3d = 0xb197, - Compute = 0xb1c0, - Kepler = 0xa140, - Dma = 0xb0b5 - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs deleted file mode 100644 index 7fb5ea8a..00000000 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs +++ /dev/null @@ -1,208 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.HLE.Gpu.Memory; -using Ryujinx.HLE.Gpu.Texture; -using System; -using System.Collections.Generic; - -namespace Ryujinx.HLE.Gpu.Engines -{ - class NvGpuEngine2d : INvGpuEngine - { - private enum CopyOperation - { - SrcCopyAnd, - RopAnd, - Blend, - SrcCopy, - Rop, - SrcCopyPremult, - BlendPremult - } - - public int[] Registers { get; private set; } - - private NvGpu Gpu; - - private Dictionary<int, NvGpuMethod> Methods; - - public NvGpuEngine2d(NvGpu Gpu) - { - this.Gpu = Gpu; - - Registers = new int[0xe00]; - - Methods = new Dictionary<int, NvGpuMethod>(); - - void AddMethod(int Meth, int Count, int Stride, NvGpuMethod Method) - { - while (Count-- > 0) - { - Methods.Add(Meth, Method); - - Meth += Stride; - } - } - - AddMethod(0xb5, 1, 1, TextureCopy); - } - - public void CallMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - if (Methods.TryGetValue(PBEntry.Method, out NvGpuMethod Method)) - { - Method(Vmm, PBEntry); - } - else - { - WriteRegister(PBEntry); - } - } - - private void TextureCopy(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - CopyOperation Operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation); - - bool SrcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0; - int SrcWidth = ReadRegister(NvGpuEngine2dReg.SrcWidth); - int SrcHeight = ReadRegister(NvGpuEngine2dReg.SrcHeight); - int SrcPitch = ReadRegister(NvGpuEngine2dReg.SrcPitch); - int SrcBlkDim = ReadRegister(NvGpuEngine2dReg.SrcBlockDimensions); - - bool DstLinear = ReadRegister(NvGpuEngine2dReg.DstLinear) != 0; - int DstWidth = ReadRegister(NvGpuEngine2dReg.DstWidth); - int DstHeight = ReadRegister(NvGpuEngine2dReg.DstHeight); - int DstPitch = ReadRegister(NvGpuEngine2dReg.DstPitch); - int DstBlkDim = ReadRegister(NvGpuEngine2dReg.DstBlockDimensions); - - TextureSwizzle SrcSwizzle = SrcLinear - ? TextureSwizzle.Pitch - : TextureSwizzle.BlockLinear; - - TextureSwizzle DstSwizzle = DstLinear - ? TextureSwizzle.Pitch - : TextureSwizzle.BlockLinear; - - int SrcBlockHeight = 1 << ((SrcBlkDim >> 4) & 0xf); - int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf); - - long SrcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress); - long DstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress); - - long SrcKey = Vmm.GetPhysicalAddress(SrcAddress); - long DstKey = Vmm.GetPhysicalAddress(DstAddress); - - bool IsSrcFb = Gpu.Engine3d.IsFrameBufferPosition(SrcKey); - bool IsDstFb = Gpu.Engine3d.IsFrameBufferPosition(DstKey); - - TextureInfo SrcTexture() - { - return new TextureInfo( - SrcAddress, - SrcWidth, - SrcHeight, - SrcPitch, - SrcBlockHeight, 1, - SrcSwizzle, - GalTextureFormat.A8B8G8R8); - } - - TextureInfo DstTexture() - { - return new TextureInfo( - DstAddress, - DstWidth, - DstHeight, - DstPitch, - DstBlockHeight, 1, - DstSwizzle, - GalTextureFormat.A8B8G8R8); - } - - //TODO: fb -> fb copies, tex -> fb copies, formats other than RGBA8, - //make it throw for unimpl stuff (like the copy mode)... - if (IsSrcFb && IsDstFb) - { - //Frame Buffer -> Frame Buffer copy. - Gpu.Renderer.FrameBuffer.Copy( - SrcKey, - DstKey, - 0, - 0, - SrcWidth, - SrcHeight, - 0, - 0, - DstWidth, - DstHeight); - } - if (IsSrcFb) - { - //Frame Buffer -> Texture copy. - Gpu.Renderer.FrameBuffer.GetBufferData(SrcKey, (byte[] Buffer) => - { - TextureInfo Src = SrcTexture(); - TextureInfo Dst = DstTexture(); - - if (Src.Width != Dst.Width || - Src.Height != Dst.Height) - { - throw new NotImplementedException("Texture resizing is not supported"); - } - - TextureWriter.Write(Vmm, Dst, Buffer); - }); - } - else if (IsDstFb) - { - byte[] Buffer = TextureReader.Read(Vmm, SrcTexture()); - - Gpu.Renderer.FrameBuffer.SetBufferData( - DstKey, - DstWidth, - DstHeight, - Buffer); - } - else - { - //Texture -> Texture copy. - TextureInfo Src = SrcTexture(); - TextureInfo Dst = DstTexture(); - - if (Src.Width != Dst.Width || - Src.Height != Dst.Height) - { - throw new NotImplementedException("Texture resizing is not supported"); - } - - TextureWriter.Write(Vmm, Dst, TextureReader.Read(Vmm, Src)); - } - } - - private long MakeInt64From2xInt32(NvGpuEngine2dReg Reg) - { - return - (long)Registers[(int)Reg + 0] << 32 | - (uint)Registers[(int)Reg + 1]; - } - - private void WriteRegister(NvGpuPBEntry PBEntry) - { - int ArgsCount = PBEntry.Arguments.Count; - - if (ArgsCount > 0) - { - Registers[PBEntry.Method] = PBEntry.Arguments[ArgsCount - 1]; - } - } - - private int ReadRegister(NvGpuEngine2dReg Reg) - { - return Registers[(int)Reg]; - } - - private void WriteRegister(NvGpuEngine2dReg Reg, int Value) - { - Registers[(int)Reg] = Value; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2dReg.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2dReg.cs deleted file mode 100644 index 29d66d46..00000000 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2dReg.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Ryujinx.HLE.Gpu.Engines -{ - enum NvGpuEngine2dReg - { - DstFormat = 0x80, - DstLinear = 0x81, - DstBlockDimensions = 0x82, - DstDepth = 0x83, - DstLayer = 0x84, - DstPitch = 0x85, - DstWidth = 0x86, - DstHeight = 0x87, - DstAddress = 0x88, - SrcFormat = 0x8c, - SrcLinear = 0x8d, - SrcBlockDimensions = 0x8e, - SrcDepth = 0x8f, - SrcLayer = 0x90, - SrcPitch = 0x91, - SrcWidth = 0x92, - SrcHeight = 0x93, - SrcAddress = 0x94, - CopyOperation = 0xab - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs deleted file mode 100644 index 0d2f3bef..00000000 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs +++ /dev/null @@ -1,895 +0,0 @@ -using Ryujinx.Graphics.Gal; -using Ryujinx.HLE.Gpu.Memory; -using Ryujinx.HLE.Gpu.Texture; -using System; -using System.Collections.Generic; - -namespace Ryujinx.HLE.Gpu.Engines -{ - class NvGpuEngine3d : INvGpuEngine - { - public int[] Registers { get; private set; } - - private NvGpu Gpu; - - private Dictionary<int, NvGpuMethod> Methods; - - private struct ConstBuffer - { - public bool Enabled; - public long Position; - public int Size; - } - - private ConstBuffer[][] ConstBuffers; - - private HashSet<long> FrameBuffers; - - private List<long>[] UploadedKeys; - - private int CurrentInstance = 0; - - public NvGpuEngine3d(NvGpu Gpu) - { - this.Gpu = Gpu; - - Registers = new int[0xe00]; - - Methods = new Dictionary<int, NvGpuMethod>(); - - void AddMethod(int Meth, int Count, int Stride, NvGpuMethod Method) - { - while (Count-- > 0) - { - Methods.Add(Meth, Method); - - Meth += Stride; - } - } - - AddMethod(0x585, 1, 1, VertexEndGl); - AddMethod(0x674, 1, 1, ClearBuffers); - AddMethod(0x6c3, 1, 1, QueryControl); - AddMethod(0x8e4, 16, 1, CbData); - AddMethod(0x904, 5, 8, CbBind); - - ConstBuffers = new ConstBuffer[6][]; - - for (int Index = 0; Index < ConstBuffers.Length; Index++) - { - ConstBuffers[Index] = new ConstBuffer[18]; - } - - FrameBuffers = new HashSet<long>(); - - UploadedKeys = new List<long>[(int)NvGpuBufferType.Count]; - - for (int i = 0; i < UploadedKeys.Length; i++) - { - UploadedKeys[i] = new List<long>(); - } - } - - public void CallMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - if (Methods.TryGetValue(PBEntry.Method, out NvGpuMethod Method)) - { - Method(Vmm, PBEntry); - } - else - { - WriteRegister(PBEntry); - } - } - - public void ResetCache() - { - foreach (List<long> Uploaded in UploadedKeys) - { - Uploaded.Clear(); - } - } - - private void VertexEndGl(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - LockCaches(); - - GalPipelineState State = new GalPipelineState(); - - SetFlip(State); - SetFrontFace(State); - SetCullFace(State); - SetDepth(State); - SetStencil(State); - SetAlphaBlending(State); - SetPrimitiveRestart(State); - - for (int FbIndex = 0; FbIndex < 8; FbIndex++) - { - SetFrameBuffer(Vmm, 0); - } - - SetZeta(Vmm); - - SetRenderTargets(); - - long[] Keys = UploadShaders(Vmm); - - Gpu.Renderer.Shader.BindProgram(); - - UploadTextures(Vmm, State, Keys); - UploadConstBuffers(Vmm, State, Keys); - UploadVertexArrays(Vmm, State); - - DispatchRender(Vmm, State); - - UnlockCaches(); - } - - private void LockCaches() - { - Gpu.Renderer.Buffer.LockCache(); - Gpu.Renderer.Rasterizer.LockCaches(); - Gpu.Renderer.Texture.LockCache(); - } - - private void UnlockCaches() - { - Gpu.Renderer.Buffer.UnlockCache(); - Gpu.Renderer.Rasterizer.UnlockCaches(); - Gpu.Renderer.Texture.UnlockCache(); - } - - private void ClearBuffers(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - int Arg0 = PBEntry.Arguments[0]; - - int FbIndex = (Arg0 >> 6) & 0xf; - - GalClearBufferFlags Flags = (GalClearBufferFlags)(Arg0 & 0x3f); - - float Red = ReadRegisterFloat(NvGpuEngine3dReg.ClearNColor + 0); - float Green = ReadRegisterFloat(NvGpuEngine3dReg.ClearNColor + 1); - float Blue = ReadRegisterFloat(NvGpuEngine3dReg.ClearNColor + 2); - float Alpha = ReadRegisterFloat(NvGpuEngine3dReg.ClearNColor + 3); - - float Depth = ReadRegisterFloat(NvGpuEngine3dReg.ClearDepth); - - int Stencil = ReadRegister(NvGpuEngine3dReg.ClearStencil); - - SetFrameBuffer(Vmm, FbIndex); - SetZeta(Vmm); - - Gpu.Renderer.Rasterizer.ClearBuffers( - Flags, - FbIndex, - Red, Green, Blue, Alpha, - Depth, - Stencil); - } - - private void SetFrameBuffer(NvGpuVmm Vmm, int FbIndex) - { - long VA = MakeInt64From2xInt32(NvGpuEngine3dReg.FrameBufferNAddress + FbIndex * 0x10); - - int Format = ReadRegister(NvGpuEngine3dReg.FrameBufferNFormat + FbIndex * 0x10); - - if (VA == 0 || Format == 0) - { - Gpu.Renderer.FrameBuffer.UnbindColor(FbIndex); - - return; - } - - long Key = Vmm.GetPhysicalAddress(VA); - - FrameBuffers.Add(Key); - - int Width = ReadRegister(NvGpuEngine3dReg.FrameBufferNWidth + FbIndex * 0x10); - int Height = ReadRegister(NvGpuEngine3dReg.FrameBufferNHeight + FbIndex * 0x10); - - float TX = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNTranslateX + FbIndex * 8); - float TY = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNTranslateY + FbIndex * 8); - - float SX = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNScaleX + FbIndex * 8); - float SY = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNScaleY + FbIndex * 8); - - int VpX = (int)MathF.Max(0, TX - MathF.Abs(SX)); - int VpY = (int)MathF.Max(0, TY - MathF.Abs(SY)); - - int VpW = (int)(TX + MathF.Abs(SX)) - VpX; - int VpH = (int)(TY + MathF.Abs(SY)) - VpY; - - GalImageFormat ImageFormat = ImageFormatConverter.ConvertFrameBuffer((GalFrameBufferFormat)Format); - - GalImage Image = new GalImage(Width, Height, ImageFormat); - - long Size = TextureHelper.GetTextureSize(Image); - - Gpu.Renderer.Texture.CreateFb(Key, Size, Image); - Gpu.Renderer.FrameBuffer.BindColor(Key, FbIndex); - - Gpu.Renderer.FrameBuffer.SetViewport(VpX, VpY, VpW, VpH); - } - - private void SetZeta(NvGpuVmm Vmm) - { - long ZA = MakeInt64From2xInt32(NvGpuEngine3dReg.ZetaAddress); - - int Format = ReadRegister(NvGpuEngine3dReg.ZetaFormat); - - bool ZetaEnable = (ReadRegister(NvGpuEngine3dReg.ZetaEnable) & 1) != 0; - - if (ZA == 0 || Format == 0 || !ZetaEnable) - { - Gpu.Renderer.FrameBuffer.UnbindZeta(); - - return; - } - - long Key = Vmm.GetPhysicalAddress(ZA); - - int Width = ReadRegister(NvGpuEngine3dReg.ZetaHoriz); - int Height = ReadRegister(NvGpuEngine3dReg.ZetaVert); - - GalImageFormat ImageFormat = ImageFormatConverter.ConvertZeta((GalZetaFormat)Format); - - GalImage Image = new GalImage(Width, Height, ImageFormat); - - long Size = TextureHelper.GetTextureSize(Image); - - Gpu.Renderer.Texture.CreateFb(Key, Size, Image); - Gpu.Renderer.FrameBuffer.BindZeta(Key); - } - - private long[] UploadShaders(NvGpuVmm Vmm) - { - long[] Keys = new long[5]; - - long BasePosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress); - - int Index = 1; - - int VpAControl = ReadRegister(NvGpuEngine3dReg.ShaderNControl); - - bool VpAEnable = (VpAControl & 1) != 0; - - if (VpAEnable) - { - //Note: The maxwell supports 2 vertex programs, usually - //only VP B is used, but in some cases VP A is also used. - //In this case, it seems to function as an extra vertex - //shader stage. - //The graphics abstraction layer has a special overload for this - //case, which should merge the two shaders into one vertex shader. - int VpAOffset = ReadRegister(NvGpuEngine3dReg.ShaderNOffset); - int VpBOffset = ReadRegister(NvGpuEngine3dReg.ShaderNOffset + 0x10); - - long VpAPos = BasePosition + (uint)VpAOffset; - long VpBPos = BasePosition + (uint)VpBOffset; - - Keys[(int)GalShaderType.Vertex] = VpBPos; - - Gpu.Renderer.Shader.Create(Vmm, VpAPos, VpBPos, GalShaderType.Vertex); - Gpu.Renderer.Shader.Bind(VpBPos); - - Index = 2; - } - - for (; Index < 6; Index++) - { - GalShaderType Type = GetTypeFromProgram(Index); - - int Control = ReadRegister(NvGpuEngine3dReg.ShaderNControl + Index * 0x10); - int Offset = ReadRegister(NvGpuEngine3dReg.ShaderNOffset + Index * 0x10); - - //Note: Vertex Program (B) is always enabled. - bool Enable = (Control & 1) != 0 || Index == 1; - - if (!Enable) - { - Gpu.Renderer.Shader.Unbind(Type); - - continue; - } - - long Key = BasePosition + (uint)Offset; - - Keys[(int)Type] = Key; - - Gpu.Renderer.Shader.Create(Vmm, Key, Type); - Gpu.Renderer.Shader.Bind(Key); - } - - return Keys; - } - - private static GalShaderType GetTypeFromProgram(int Program) - { - switch (Program) - { - case 0: - case 1: return GalShaderType.Vertex; - case 2: return GalShaderType.TessControl; - case 3: return GalShaderType.TessEvaluation; - case 4: return GalShaderType.Geometry; - case 5: return GalShaderType.Fragment; - } - - throw new ArgumentOutOfRangeException(nameof(Program)); - } - - private void SetFlip(GalPipelineState State) - { - State.FlipX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX); - State.FlipY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY); - } - - private void SetFrontFace(GalPipelineState State) - { - float SignX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX); - float SignY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY); - - GalFrontFace FrontFace = (GalFrontFace)ReadRegister(NvGpuEngine3dReg.FrontFace); - - //Flipping breaks facing. Flipping front facing too fixes it - if (SignX != SignY) - { - switch (FrontFace) - { - case GalFrontFace.CW: - FrontFace = GalFrontFace.CCW; - break; - - case GalFrontFace.CCW: - FrontFace = GalFrontFace.CW; - break; - } - } - - State.FrontFace = FrontFace; - } - - private void SetCullFace(GalPipelineState State) - { - State.CullFaceEnabled = (ReadRegister(NvGpuEngine3dReg.CullFaceEnable) & 1) != 0; - - if (State.CullFaceEnabled) - { - State.CullFace = (GalCullFace)ReadRegister(NvGpuEngine3dReg.CullFace); - } - } - - private void SetDepth(GalPipelineState State) - { - State.DepthTestEnabled = (ReadRegister(NvGpuEngine3dReg.DepthTestEnable) & 1) != 0; - - if (State.DepthTestEnabled) - { - State.DepthFunc = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.DepthTestFunction); - } - } - - private void SetStencil(GalPipelineState State) - { - State.StencilTestEnabled = (ReadRegister(NvGpuEngine3dReg.StencilEnable) & 1) != 0; - - if (State.StencilTestEnabled) - { - State.StencilBackFuncFunc = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.StencilBackFuncFunc); - State.StencilBackFuncRef = ReadRegister(NvGpuEngine3dReg.StencilBackFuncRef); - State.StencilBackFuncMask = (uint)ReadRegister(NvGpuEngine3dReg.StencilBackFuncMask); - State.StencilBackOpFail = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilBackOpFail); - State.StencilBackOpZFail = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilBackOpZFail); - State.StencilBackOpZPass = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilBackOpZPass); - State.StencilBackMask = (uint)ReadRegister(NvGpuEngine3dReg.StencilBackMask); - - State.StencilFrontFuncFunc = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.StencilFrontFuncFunc); - State.StencilFrontFuncRef = ReadRegister(NvGpuEngine3dReg.StencilFrontFuncRef); - State.StencilFrontFuncMask = (uint)ReadRegister(NvGpuEngine3dReg.StencilFrontFuncMask); - State.StencilFrontOpFail = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilFrontOpFail); - State.StencilFrontOpZFail = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilFrontOpZFail); - State.StencilFrontOpZPass = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilFrontOpZPass); - State.StencilFrontMask = (uint)ReadRegister(NvGpuEngine3dReg.StencilFrontMask); - } - } - - private void SetAlphaBlending(GalPipelineState State) - { - //TODO: Support independent blend properly. - State.BlendEnabled = (ReadRegister(NvGpuEngine3dReg.IBlendNEnable) & 1) != 0; - - if (State.BlendEnabled) - { - State.BlendSeparateAlpha = (ReadRegister(NvGpuEngine3dReg.IBlendNSeparateAlpha) & 1) != 0; - - State.BlendEquationRgb = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.IBlendNEquationRgb); - State.BlendFuncSrcRgb = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcRgb); - State.BlendFuncDstRgb = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstRgb); - State.BlendEquationAlpha = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.IBlendNEquationAlpha); - State.BlendFuncSrcAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcAlpha); - State.BlendFuncDstAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstAlpha); - } - } - - private void SetPrimitiveRestart(GalPipelineState State) - { - State.PrimitiveRestartEnabled = (ReadRegister(NvGpuEngine3dReg.PrimRestartEnable) & 1) != 0; - - if (State.PrimitiveRestartEnabled) - { - State.PrimitiveRestartIndex = (uint)ReadRegister(NvGpuEngine3dReg.PrimRestartIndex); - } - } - - private void SetRenderTargets() - { - bool SeparateFragData = (ReadRegister(NvGpuEngine3dReg.RTSeparateFragData) & 1) != 0; - - if (SeparateFragData) - { - uint Control = (uint)(ReadRegister(NvGpuEngine3dReg.RTControl)); - - uint Count = Control & 0xf; - - int[] Map = new int[Count]; - - for (int i = 0; i < Count; i++) - { - int Shift = 4 + i * 3; - - Map[i] = (int)((Control >> Shift) & 7); - } - - Gpu.Renderer.FrameBuffer.SetMap(Map); - } - else - { - Gpu.Renderer.FrameBuffer.SetMap(null); - } - } - - private void UploadTextures(NvGpuVmm Vmm, GalPipelineState State, long[] Keys) - { - long BaseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress); - - int TextureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex); - - int TexIndex = 0; - - for (int Index = 0; Index < Keys.Length; Index++) - { - foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.Shader.GetTextureUsage(Keys[Index])) - { - long Position; - - if (DeclInfo.IsCb) - { - Position = ConstBuffers[Index][DeclInfo.Cbuf].Position; - } - else - { - Position = ConstBuffers[Index][TextureCbIndex].Position; - } - - int TextureHandle = Vmm.ReadInt32(Position + DeclInfo.Index * 4); - - UploadTexture(Vmm, TexIndex, TextureHandle); - - TexIndex++; - } - } - } - - private void UploadTexture(NvGpuVmm Vmm, int TexIndex, int TextureHandle) - { - if (TextureHandle == 0) - { - //TODO: Is this correct? - //Some games like puyo puyo will have 0 handles. - //It may be just normal behaviour or a bug caused by sync issues. - //The game does initialize the value properly after through. - return; - } - - int TicIndex = (TextureHandle >> 0) & 0xfffff; - int TscIndex = (TextureHandle >> 20) & 0xfff; - - long TicPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexHeaderPoolOffset); - long TscPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexSamplerPoolOffset); - - TicPosition += TicIndex * 0x20; - TscPosition += TscIndex * 0x20; - - GalTextureSampler Sampler = TextureFactory.MakeSampler(Gpu, Vmm, TscPosition); - - long Key = Vmm.ReadInt64(TicPosition + 4) & 0xffffffffffff; - - Key = Vmm.GetPhysicalAddress(Key); - - if (Key == -1) - { - //FIXME: Should'nt ignore invalid addresses. - return; - } - - if (IsFrameBufferPosition(Key)) - { - //This texture is a frame buffer texture, - //we shouldn't read anything from memory and bind - //the frame buffer texture instead, since we're not - //really writing anything to memory. - Gpu.Renderer.FrameBuffer.BindTexture(Key, TexIndex); - } - else - { - GalImage NewImage = TextureFactory.MakeTexture(Vmm, TicPosition); - - long Size = (uint)TextureHelper.GetTextureSize(NewImage); - - bool HasCachedTexture = false; - - if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalImage Image)) - { - if (NewImage.Equals(Image) && !QueryKeyUpload(Vmm, Key, Size, NvGpuBufferType.Texture)) - { - Gpu.Renderer.Texture.Bind(Key, TexIndex); - - HasCachedTexture = true; - } - } - - if (!HasCachedTexture) - { - byte[] Data = TextureFactory.GetTextureData(Vmm, TicPosition); - - Gpu.Renderer.Texture.Create(Key, Data, NewImage); - } - - Gpu.Renderer.Texture.Bind(Key, TexIndex); - } - - Gpu.Renderer.Texture.SetSampler(Sampler); - } - - private void UploadConstBuffers(NvGpuVmm Vmm, GalPipelineState State, long[] Keys) - { - for (int Stage = 0; Stage < Keys.Length; Stage++) - { - foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.Shader.GetConstBufferUsage(Keys[Stage])) - { - ConstBuffer Cb = ConstBuffers[Stage][DeclInfo.Cbuf]; - - if (!Cb.Enabled) - { - continue; - } - - long Key = Vmm.GetPhysicalAddress(Cb.Position); - - if (QueryKeyUpload(Vmm, Key, Cb.Size, NvGpuBufferType.ConstBuffer)) - { - IntPtr Source = Vmm.GetHostAddress(Cb.Position, Cb.Size); - - Gpu.Renderer.Buffer.SetData(Key, Cb.Size, Source); - } - - State.ConstBufferKeys[Stage][DeclInfo.Cbuf] = Key; - } - } - } - - private void UploadVertexArrays(NvGpuVmm Vmm, GalPipelineState State) - { - long IndexPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.IndexArrayAddress); - - long IboKey = Vmm.GetPhysicalAddress(IndexPosition); - - int IndexEntryFmt = ReadRegister(NvGpuEngine3dReg.IndexArrayFormat); - int IndexCount = ReadRegister(NvGpuEngine3dReg.IndexBatchCount); - - GalIndexFormat IndexFormat = (GalIndexFormat)IndexEntryFmt; - - int IndexEntrySize = 1 << IndexEntryFmt; - - if (IndexEntrySize > 4) - { - throw new InvalidOperationException(); - } - - if (IndexCount != 0) - { - int IbSize = IndexCount * IndexEntrySize; - - bool IboCached = Gpu.Renderer.Rasterizer.IsIboCached(IboKey, (uint)IbSize); - - if (!IboCached || QueryKeyUpload(Vmm, IboKey, (uint)IbSize, NvGpuBufferType.Index)) - { - IntPtr DataAddress = Vmm.GetHostAddress(IndexPosition, IbSize); - - Gpu.Renderer.Rasterizer.CreateIbo(IboKey, IbSize, DataAddress); - } - - Gpu.Renderer.Rasterizer.SetIndexArray(IbSize, IndexFormat); - } - - List<GalVertexAttrib>[] Attribs = new List<GalVertexAttrib>[32]; - - for (int Attr = 0; Attr < 16; Attr++) - { - int Packed = ReadRegister(NvGpuEngine3dReg.VertexAttribNFormat + Attr); - - int ArrayIndex = Packed & 0x1f; - - if (Attribs[ArrayIndex] == null) - { - Attribs[ArrayIndex] = new List<GalVertexAttrib>(); - } - - Attribs[ArrayIndex].Add(new GalVertexAttrib( - Attr, - ((Packed >> 6) & 0x1) != 0, - (Packed >> 7) & 0x3fff, - (GalVertexAttribSize)((Packed >> 21) & 0x3f), - (GalVertexAttribType)((Packed >> 27) & 0x7), - ((Packed >> 31) & 0x1) != 0)); - } - - State.VertexBindings = new GalVertexBinding[32]; - - for (int Index = 0; Index < 32; Index++) - { - if (Attribs[Index] == null) - { - continue; - } - - int Control = ReadRegister(NvGpuEngine3dReg.VertexArrayNControl + Index * 4); - - bool Enable = (Control & 0x1000) != 0; - - if (!Enable) - { - continue; - } - - long VertexPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.VertexArrayNAddress + Index * 4); - long VertexEndPos = MakeInt64From2xInt32(NvGpuEngine3dReg.VertexArrayNEndAddr + Index * 2); - - int VertexDivisor = ReadRegister(NvGpuEngine3dReg.VertexArrayNDivisor + Index * 4); - - bool Instanced = (ReadRegister(NvGpuEngine3dReg.VertexArrayNInstance + Index) & 1) != 0; - - int Stride = Control & 0xfff; - - if (Instanced && VertexDivisor != 0) - { - VertexPosition += Stride * (CurrentInstance / VertexDivisor); - } - - if (VertexPosition > VertexEndPos) - { - //Instance is invalid, ignore the draw call - continue; - } - - long VboKey = Vmm.GetPhysicalAddress(VertexPosition); - - long VbSize = (VertexEndPos - VertexPosition) + 1; - - bool VboCached = Gpu.Renderer.Rasterizer.IsVboCached(VboKey, VbSize); - - if (!VboCached || QueryKeyUpload(Vmm, VboKey, VbSize, NvGpuBufferType.Vertex)) - { - IntPtr DataAddress = Vmm.GetHostAddress(VertexPosition, VbSize); - - Gpu.Renderer.Rasterizer.CreateVbo(VboKey, (int)VbSize, DataAddress); - } - - State.VertexBindings[Index].Enabled = true; - State.VertexBindings[Index].Stride = Stride; - State.VertexBindings[Index].VboKey = VboKey; - State.VertexBindings[Index].Instanced = Instanced; - State.VertexBindings[Index].Divisor = VertexDivisor; - State.VertexBindings[Index].Attribs = Attribs[Index].ToArray(); - } - } - - private void DispatchRender(NvGpuVmm Vmm, GalPipelineState State) - { - int IndexCount = ReadRegister(NvGpuEngine3dReg.IndexBatchCount); - int PrimCtrl = ReadRegister(NvGpuEngine3dReg.VertexBeginGl); - - GalPrimitiveType PrimType = (GalPrimitiveType)(PrimCtrl & 0xffff); - - bool InstanceNext = ((PrimCtrl >> 26) & 1) != 0; - bool InstanceCont = ((PrimCtrl >> 27) & 1) != 0; - - if (InstanceNext && InstanceCont) - { - throw new InvalidOperationException("GPU tried to increase and reset instance count at the same time"); - } - - if (InstanceNext) - { - CurrentInstance++; - } - else if (!InstanceCont) - { - CurrentInstance = 0; - } - - State.Instance = CurrentInstance; - - Gpu.Renderer.Pipeline.Bind(State); - - if (IndexCount != 0) - { - int IndexEntryFmt = ReadRegister(NvGpuEngine3dReg.IndexArrayFormat); - int IndexFirst = ReadRegister(NvGpuEngine3dReg.IndexBatchFirst); - int VertexBase = ReadRegister(NvGpuEngine3dReg.VertexArrayElemBase); - - long IndexPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.IndexArrayAddress); - - long IboKey = Vmm.GetPhysicalAddress(IndexPosition); - - Gpu.Renderer.Rasterizer.DrawElements(IboKey, IndexFirst, VertexBase, PrimType); - } - else - { - int VertexFirst = ReadRegister(NvGpuEngine3dReg.VertexArrayFirst); - int VertexCount = ReadRegister(NvGpuEngine3dReg.VertexArrayCount); - - Gpu.Renderer.Rasterizer.DrawArrays(VertexFirst, VertexCount, PrimType); - } - - //Is the GPU really clearing those registers after draw? - WriteRegister(NvGpuEngine3dReg.IndexBatchFirst, 0); - WriteRegister(NvGpuEngine3dReg.IndexBatchCount, 0); - } - - private enum QueryMode - { - WriteSeq, - Sync, - WriteCounterAndTimestamp - } - - private void QueryControl(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - WriteRegister(PBEntry); - - long Position = MakeInt64From2xInt32(NvGpuEngine3dReg.QueryAddress); - - int Seq = Registers[(int)NvGpuEngine3dReg.QuerySequence]; - int Ctrl = Registers[(int)NvGpuEngine3dReg.QueryControl]; - - QueryMode Mode = (QueryMode)(Ctrl & 3); - - switch (Mode) - { - case QueryMode.WriteSeq: Vmm.WriteInt32(Position, Seq); break; - - case QueryMode.WriteCounterAndTimestamp: - { - //TODO: Implement counters. - long Counter = 1; - - long Timestamp = (uint)Environment.TickCount; - - Timestamp = (long)(Timestamp * 615384.615385); - - Vmm.WriteInt64(Position + 0, Counter); - Vmm.WriteInt64(Position + 8, Timestamp); - - break; - } - } - } - - private void CbData(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - long Position = MakeInt64From2xInt32(NvGpuEngine3dReg.ConstBufferAddress); - - int Offset = ReadRegister(NvGpuEngine3dReg.ConstBufferOffset); - - foreach (int Arg in PBEntry.Arguments) - { - Vmm.WriteInt32(Position + Offset, Arg); - - Offset += 4; - } - - WriteRegister(NvGpuEngine3dReg.ConstBufferOffset, Offset); - - UploadedKeys[(int)NvGpuBufferType.ConstBuffer].Clear(); - } - - private void CbBind(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - int Stage = (PBEntry.Method - 0x904) >> 3; - - int Index = PBEntry.Arguments[0]; - - bool Enabled = (Index & 1) != 0; - - Index = (Index >> 4) & 0x1f; - - long Position = MakeInt64From2xInt32(NvGpuEngine3dReg.ConstBufferAddress); - - long CbKey = Vmm.GetPhysicalAddress(Position); - - int Size = ReadRegister(NvGpuEngine3dReg.ConstBufferSize); - - if (!Gpu.Renderer.Buffer.IsCached(CbKey, Size)) - { - Gpu.Renderer.Buffer.Create(CbKey, Size); - } - - ConstBuffer Cb = ConstBuffers[Stage][Index]; - - if (Cb.Position != Position || Cb.Enabled != Enabled || Cb.Size != Size) - { - ConstBuffers[Stage][Index].Position = Position; - ConstBuffers[Stage][Index].Enabled = Enabled; - ConstBuffers[Stage][Index].Size = Size; - } - } - - private float GetFlipSign(NvGpuEngine3dReg Reg) - { - return MathF.Sign(ReadRegisterFloat(Reg)); - } - - private long MakeInt64From2xInt32(NvGpuEngine3dReg Reg) - { - return - (long)Registers[(int)Reg + 0] << 32 | - (uint)Registers[(int)Reg + 1]; - } - - private void WriteRegister(NvGpuPBEntry PBEntry) - { - int ArgsCount = PBEntry.Arguments.Count; - - if (ArgsCount > 0) - { - Registers[PBEntry.Method] = PBEntry.Arguments[ArgsCount - 1]; - } - } - - private int ReadRegister(NvGpuEngine3dReg Reg) - { - return Registers[(int)Reg]; - } - - private float ReadRegisterFloat(NvGpuEngine3dReg Reg) - { - return BitConverter.Int32BitsToSingle(ReadRegister(Reg)); - } - - private void WriteRegister(NvGpuEngine3dReg Reg, int Value) - { - Registers[(int)Reg] = Value; - } - - public bool IsFrameBufferPosition(long Position) - { - return FrameBuffers.Contains(Position); - } - - private bool QueryKeyUpload(NvGpuVmm Vmm, long Key, long Size, NvGpuBufferType Type) - { - List<long> Uploaded = UploadedKeys[(int)Type]; - - if (Uploaded.Contains(Key)) - { - return false; - } - - Uploaded.Add(Key); - - return Vmm.IsRegionModified(Key, Size, Type); - } - } -} diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs deleted file mode 100644 index ace324e9..00000000 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs +++ /dev/null @@ -1,101 +0,0 @@ -namespace Ryujinx.HLE.Gpu.Engines -{ - enum NvGpuEngine3dReg - { - FrameBufferNAddress = 0x200, - FrameBufferNWidth = 0x202, - FrameBufferNHeight = 0x203, - FrameBufferNFormat = 0x204, - ViewportNScaleX = 0x280, - ViewportNScaleY = 0x281, - ViewportNScaleZ = 0x282, - ViewportNTranslateX = 0x283, - ViewportNTranslateY = 0x284, - ViewportNTranslateZ = 0x285, - ViewportNHoriz = 0x300, - ViewportNVert = 0x301, - VertexArrayFirst = 0x35d, - VertexArrayCount = 0x35e, - ClearNColor = 0x360, - ClearDepth = 0x364, - ClearStencil = 0x368, - StencilBackFuncRef = 0x3d5, - StencilBackMask = 0x3d6, - StencilBackFuncMask = 0x3d7, - RTSeparateFragData = 0x3eb, - ZetaAddress = 0x3f8, - ZetaFormat = 0x3fa, - ZetaBlockDimensions = 0x3fb, - ZetaLayerStride = 0x3fc, - VertexAttribNFormat = 0x458, - RTControl = 0x487, - ZetaHoriz = 0x48a, - ZetaVert = 0x48b, - ZetaArrayMode = 0x48c, - DepthTestEnable = 0x4b3, - IBlendEnable = 0x4b9, - DepthTestFunction = 0x4c3, - BlendSeparateAlpha = 0x4cf, - BlendEquationRgb = 0x4d0, - BlendFuncSrcRgb = 0x4d1, - BlendFuncDstRgb = 0x4d2, - BlendEquationAlpha = 0x4d3, - BlendFuncSrcAlpha = 0x4d4, - BlendFuncDstAlpha = 0x4d6, - BlendEnableMaster = 0x4d7, - IBlendNEnable = 0x4d8, - StencilEnable = 0x4e0, - StencilFrontOpFail = 0x4e1, - StencilFrontOpZFail = 0x4e2, - StencilFrontOpZPass = 0x4e3, - StencilFrontFuncFunc = 0x4e4, - StencilFrontFuncRef = 0x4e5, - StencilFrontFuncMask = 0x4e6, - StencilFrontMask = 0x4e7, - VertexArrayElemBase = 0x50d, - VertexArrayInstBase = 0x50e, - ZetaEnable = 0x54e, - TexHeaderPoolOffset = 0x55d, - TexSamplerPoolOffset = 0x557, - StencilTwoSideEnable = 0x565, - StencilBackOpFail = 0x566, - StencilBackOpZFail = 0x567, - StencilBackOpZPass = 0x568, - StencilBackFuncFunc = 0x569, - ShaderAddress = 0x582, - VertexBeginGl = 0x586, - PrimRestartEnable = 0x591, - PrimRestartIndex = 0x592, - IndexArrayAddress = 0x5f2, - IndexArrayEndAddr = 0x5f4, - IndexArrayFormat = 0x5f6, - IndexBatchFirst = 0x5f7, - IndexBatchCount = 0x5f8, - VertexArrayNInstance = 0x620, - CullFaceEnable = 0x646, - FrontFace = 0x647, - CullFace = 0x648, - QueryAddress = 0x6c0, - QuerySequence = 0x6c2, - QueryControl = 0x6c3, - VertexArrayNControl = 0x700, - VertexArrayNAddress = 0x701, - VertexArrayNDivisor = 0x703, - IBlendNSeparateAlpha = 0x780, - IBlendNEquationRgb = 0x781, - IBlendNFuncSrcRgb = 0x782, - IBlendNFuncDstRgb = 0x783, - IBlendNEquationAlpha = 0x784, - IBlendNFuncSrcAlpha = 0x785, - IBlendNFuncDstAlpha = 0x786, - VertexArrayNEndAddr = 0x7c0, - ShaderNControl = 0x800, - ShaderNOffset = 0x801, - ShaderNMaxGprs = 0x803, - ShaderNType = 0x804, - ConstBufferSize = 0x8e0, - ConstBufferAddress = 0x8e1, - ConstBufferOffset = 0x8e3, - TextureCbIndex = 0x982 - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDma.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDma.cs deleted file mode 100644 index 7e355e8d..00000000 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDma.cs +++ /dev/null @@ -1,143 +0,0 @@ -using Ryujinx.HLE.Gpu.Memory; -using Ryujinx.HLE.Gpu.Texture; -using System.Collections.Generic; - -namespace Ryujinx.HLE.Gpu.Engines -{ - class NvGpuEngineDma : INvGpuEngine - { - public int[] Registers { get; private set; } - - private NvGpu Gpu; - - private Dictionary<int, NvGpuMethod> Methods; - - public NvGpuEngineDma(NvGpu Gpu) - { - this.Gpu = Gpu; - - Registers = new int[0x1d6]; - - Methods = new Dictionary<int, NvGpuMethod>(); - - void AddMethod(int Meth, int Count, int Stride, NvGpuMethod Method) - { - while (Count-- > 0) - { - Methods.Add(Meth, Method); - - Meth += Stride; - } - } - - AddMethod(0xc0, 1, 1, Execute); - } - - public void CallMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - if (Methods.TryGetValue(PBEntry.Method, out NvGpuMethod Method)) - { - Method(Vmm, PBEntry); - } - else - { - WriteRegister(PBEntry); - } - } - - private void Execute(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - int Control = PBEntry.Arguments[0]; - - bool SrcLinear = ((Control >> 7) & 1) != 0; - bool DstLinear = ((Control >> 8) & 1) != 0; - - long SrcAddress = MakeInt64From2xInt32(NvGpuEngineDmaReg.SrcAddress); - long DstAddress = MakeInt64From2xInt32(NvGpuEngineDmaReg.DstAddress); - - int SrcPitch = ReadRegister(NvGpuEngineDmaReg.SrcPitch); - int DstPitch = ReadRegister(NvGpuEngineDmaReg.DstPitch); - - int DstBlkDim = ReadRegister(NvGpuEngineDmaReg.DstBlkDim); - int DstSizeX = ReadRegister(NvGpuEngineDmaReg.DstSizeX); - int DstSizeY = ReadRegister(NvGpuEngineDmaReg.DstSizeY); - int DstSizeZ = ReadRegister(NvGpuEngineDmaReg.DstSizeZ); - int DstPosXY = ReadRegister(NvGpuEngineDmaReg.DstPosXY); - int DstPosZ = ReadRegister(NvGpuEngineDmaReg.DstPosZ); - - int SrcBlkDim = ReadRegister(NvGpuEngineDmaReg.SrcBlkDim); - int SrcSizeX = ReadRegister(NvGpuEngineDmaReg.SrcSizeX); - int SrcSizeY = ReadRegister(NvGpuEngineDmaReg.SrcSizeY); - int SrcSizeZ = ReadRegister(NvGpuEngineDmaReg.SrcSizeZ); - int SrcPosXY = ReadRegister(NvGpuEngineDmaReg.SrcPosXY); - int SrcPosZ = ReadRegister(NvGpuEngineDmaReg.SrcPosZ); - - int DstPosX = (DstPosXY >> 0) & 0xffff; - int DstPosY = (DstPosXY >> 16) & 0xffff; - - int SrcPosX = (SrcPosXY >> 0) & 0xffff; - int SrcPosY = (SrcPosXY >> 16) & 0xffff; - - int SrcBlockHeight = 1 << ((SrcBlkDim >> 4) & 0xf); - int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf); - - ISwizzle SrcSwizzle; - - if (SrcLinear) - { - SrcSwizzle = new LinearSwizzle(SrcPitch, 1); - } - else - { - SrcSwizzle = new BlockLinearSwizzle(SrcSizeX, 1, SrcBlockHeight); - } - - ISwizzle DstSwizzle; - - if (DstLinear) - { - DstSwizzle = new LinearSwizzle(DstPitch, 1); - } - else - { - DstSwizzle = new BlockLinearSwizzle(DstSizeX, 1, DstBlockHeight); - } - - for (int Y = 0; Y < DstSizeY; Y++) - for (int X = 0; X < DstSizeX; X++) - { - long SrcOffset = SrcAddress + (uint)SrcSwizzle.GetSwizzleOffset(X, Y); - long DstOffset = DstAddress + (uint)DstSwizzle.GetSwizzleOffset(X, Y); - - Vmm.WriteByte(DstOffset, Vmm.ReadByte(SrcOffset)); - } - } - - private long MakeInt64From2xInt32(NvGpuEngineDmaReg Reg) - { - return - (long)Registers[(int)Reg + 0] << 32 | - (uint)Registers[(int)Reg + 1]; - } - - private void WriteRegister(NvGpuPBEntry PBEntry) - { - int ArgsCount = PBEntry.Arguments.Count; - - if (ArgsCount > 0) - { - Registers[PBEntry.Method] = PBEntry.Arguments[ArgsCount - 1]; - } - } - - private int ReadRegister(NvGpuEngineDmaReg Reg) - { - return Registers[(int)Reg]; - } - - private void WriteRegister(NvGpuEngineDmaReg Reg, int Value) - { - Registers[(int)Reg] = Value; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDmaReg.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDmaReg.cs deleted file mode 100644 index 835a822d..00000000 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDmaReg.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Ryujinx.HLE.Gpu.Engines -{ - enum NvGpuEngineDmaReg - { - SrcAddress = 0x100, - DstAddress = 0x102, - SrcPitch = 0x104, - DstPitch = 0x105, - DstBlkDim = 0x1c3, - DstSizeX = 0x1c4, - DstSizeY = 0x1c5, - DstSizeZ = 0x1c6, - DstPosZ = 0x1c7, - DstPosXY = 0x1c8, - SrcBlkDim = 0x1ca, - SrcSizeX = 0x1cb, - SrcSizeY = 0x1cc, - SrcSizeZ = 0x1cd, - SrcPosZ = 0x1ce, - SrcPosXY = 0x1cf - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuFifo.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuFifo.cs deleted file mode 100644 index 0e626654..00000000 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuFifo.cs +++ /dev/null @@ -1,198 +0,0 @@ -using Ryujinx.HLE.Gpu.Memory; -using System.Collections.Concurrent; -using System.Threading; - -namespace Ryujinx.HLE.Gpu.Engines -{ - class NvGpuFifo - { - private const int MacrosCount = 0x80; - private const int MacroIndexMask = MacrosCount - 1; - - //Note: The size of the macro memory is unknown, we just make - //a guess here and use 256kb as the size. Increase if needed. - private const int MmeWords = 256 * 256; - - private NvGpu Gpu; - - private ConcurrentQueue<(NvGpuVmm, NvGpuPBEntry[])> BufferQueue; - - private NvGpuEngine[] SubChannels; - - public AutoResetEvent Event { get; private set; } - - private struct CachedMacro - { - public int Position { get; private set; } - - private MacroInterpreter Interpreter; - - public CachedMacro(NvGpuFifo PFifo, INvGpuEngine Engine, int Position) - { - this.Position = Position; - - Interpreter = new MacroInterpreter(PFifo, Engine); - } - - public void PushParam(int Param) - { - Interpreter?.Fifo.Enqueue(Param); - } - - public void Execute(NvGpuVmm Vmm, int[] Mme, int Param) - { - Interpreter?.Execute(Vmm, Mme, Position, Param); - } - } - - private int CurrMacroPosition; - private int CurrMacroBindIndex; - - private CachedMacro[] Macros; - - private int[] Mme; - - public NvGpuFifo(NvGpu Gpu) - { - this.Gpu = Gpu; - - BufferQueue = new ConcurrentQueue<(NvGpuVmm, NvGpuPBEntry[])>(); - - SubChannels = new NvGpuEngine[8]; - - Macros = new CachedMacro[MacrosCount]; - - Mme = new int[MmeWords]; - - Event = new AutoResetEvent(false); - } - - public void PushBuffer(NvGpuVmm Vmm, NvGpuPBEntry[] Buffer) - { - BufferQueue.Enqueue((Vmm, Buffer)); - - Event.Set(); - } - - public void DispatchCalls() - { - while (Step()); - } - - private (NvGpuVmm Vmm, NvGpuPBEntry[] Pb) Curr; - - private int CurrPbEntryIndex; - - public bool Step() - { - while (Curr.Pb == null || Curr.Pb.Length <= CurrPbEntryIndex) - { - if (!BufferQueue.TryDequeue(out Curr)) - { - return false; - } - - Gpu.Engine3d.ResetCache(); - - CurrPbEntryIndex = 0; - } - - CallMethod(Curr.Vmm, Curr.Pb[CurrPbEntryIndex++]); - - return true; - } - - private void CallMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - if (PBEntry.Method < 0x80) - { - switch ((NvGpuFifoMeth)PBEntry.Method) - { - case NvGpuFifoMeth.BindChannel: - { - NvGpuEngine Engine = (NvGpuEngine)PBEntry.Arguments[0]; - - SubChannels[PBEntry.SubChannel] = Engine; - - break; - } - - case NvGpuFifoMeth.SetMacroUploadAddress: - { - CurrMacroPosition = PBEntry.Arguments[0]; - - break; - } - - case NvGpuFifoMeth.SendMacroCodeData: - { - foreach (int Arg in PBEntry.Arguments) - { - Mme[CurrMacroPosition++] = Arg; - } - break; - } - - case NvGpuFifoMeth.SetMacroBindingIndex: - { - CurrMacroBindIndex = PBEntry.Arguments[0]; - - break; - } - - case NvGpuFifoMeth.BindMacro: - { - int Position = PBEntry.Arguments[0]; - - Macros[CurrMacroBindIndex] = new CachedMacro(this, Gpu.Engine3d, Position); - - break; - } - } - } - else - { - switch (SubChannels[PBEntry.SubChannel]) - { - case NvGpuEngine._2d: Call2dMethod (Vmm, PBEntry); break; - case NvGpuEngine._3d: Call3dMethod (Vmm, PBEntry); break; - case NvGpuEngine.Dma: CallDmaMethod(Vmm, PBEntry); break; - } - } - } - - private void Call2dMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - Gpu.Engine2d.CallMethod(Vmm, PBEntry); - } - - private void Call3dMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - if (PBEntry.Method < 0xe00) - { - Gpu.Engine3d.CallMethod(Vmm, PBEntry); - } - else - { - int MacroIndex = (PBEntry.Method >> 1) & MacroIndexMask; - - if ((PBEntry.Method & 1) != 0) - { - foreach (int Arg in PBEntry.Arguments) - { - Macros[MacroIndex].PushParam(Arg); - } - } - else - { - Macros[MacroIndex].Execute(Vmm, Mme, PBEntry.Arguments[0]); - } - } - } - - private void CallDmaMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) - { - Gpu.EngineDma.CallMethod(Vmm, PBEntry); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuFifoMeth.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuFifoMeth.cs deleted file mode 100644 index ffd179f2..00000000 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuFifoMeth.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.HLE.Gpu.Engines -{ - enum NvGpuFifoMeth - { - BindChannel = 0, - SetMacroUploadAddress = 0x45, - SendMacroCodeData = 0x46, - SetMacroBindingIndex = 0x47, - BindMacro = 0x48 - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuMethod.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuMethod.cs deleted file mode 100644 index 04c92f2a..00000000 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuMethod.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Ryujinx.HLE.Gpu.Memory; - -namespace Ryujinx.HLE.Gpu.Engines -{ - delegate void NvGpuMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry); -}
\ No newline at end of file |
