diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-09-18 01:30:35 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-09-18 01:30:35 -0300 |
| commit | d4187aaa9d7194aa26d04aee838edbc3a38f1862 (patch) | |
| tree | 06fe725c1067b4aeca21749799b835d85e7d2787 /Ryujinx.Graphics/NvGpuEngineP2mf.cs | |
| parent | bec95cacc1061f91373a1e3a1411981af7fe2e4e (diff) | |
Allow "reinterpretation" of framebuffer/zeta formats (#418)
* (Re)Implement format reinterpretation, other changes
* Implement writeback to guest memory, some refactoring
* More refactoring, implement reinterpretation the old way again
* Clean up
* Some fixes on M2MF (old Dma engine), added partial support for P2MF, fix conditional ssy, add Z24S8 zeta format, other fixes
* nit: Formatting
* Address PR feedback
Diffstat (limited to 'Ryujinx.Graphics/NvGpuEngineP2mf.cs')
| -rw-r--r-- | Ryujinx.Graphics/NvGpuEngineP2mf.cs | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/Ryujinx.Graphics/NvGpuEngineP2mf.cs b/Ryujinx.Graphics/NvGpuEngineP2mf.cs new file mode 100644 index 00000000..842dfc52 --- /dev/null +++ b/Ryujinx.Graphics/NvGpuEngineP2mf.cs @@ -0,0 +1,102 @@ +using Ryujinx.Graphics.Memory; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace Ryujinx.Graphics +{ + public class NvGpuEngineP2mf : INvGpuEngine + { + public int[] Registers { get; private set; } + + private NvGpu Gpu; + + private Dictionary<int, NvGpuMethod> Methods; + + private ReadOnlyCollection<int> DataBuffer; + + public NvGpuEngineP2mf(NvGpu Gpu) + { + this.Gpu = Gpu; + + Registers = new int[0x80]; + + 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(0x6c, 1, 1, Execute); + AddMethod(0x6d, 1, 1, PushData); + } + + 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) + { + //TODO: Some registers and copy modes are still not implemented. + int Control = PBEntry.Arguments[0]; + + long DstAddress = MakeInt64From2xInt32(NvGpuEngineP2mfReg.DstAddress); + + int LineLengthIn = ReadRegister(NvGpuEngineP2mfReg.LineLengthIn); + + DataBuffer = null; + + Gpu.Fifo.Step(); + + for (int Offset = 0; Offset < LineLengthIn; Offset += 4) + { + Vmm.WriteInt32(DstAddress + Offset, DataBuffer[Offset >> 2]); + } + } + + private void PushData(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) + { + DataBuffer = PBEntry.Arguments; + } + + private long MakeInt64From2xInt32(NvGpuEngineP2mfReg 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(NvGpuEngineP2mfReg Reg) + { + return Registers[(int)Reg]; + } + + private void WriteRegister(NvGpuEngineP2mfReg Reg, int Value) + { + Registers[(int)Reg] = Value; + } + } +}
\ No newline at end of file |
