From c86aacde76b5f8e503e2b412385c8491ecc86b3b Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 3 Dec 2018 00:38:47 -0200 Subject: NVDEC implementation using FFmpeg (#443) * Initial nvdec implementation using FFmpeg * Fix swapped channels on the video decoder and the G8R8 texture format * Fix texture samplers not being set properly (regression) * Rebased * Remove unused code introduced on the rebase * Add support for RGBA8 output format on the video image composer * Correct spacing * Some fixes for rebase and other tweaks * Allow size mismatch on frame copy * Get rid of GetHostAddress calls on VDec --- Ryujinx.Graphics/CdmaProcessor.cs | 99 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 Ryujinx.Graphics/CdmaProcessor.cs (limited to 'Ryujinx.Graphics/CdmaProcessor.cs') diff --git a/Ryujinx.Graphics/CdmaProcessor.cs b/Ryujinx.Graphics/CdmaProcessor.cs new file mode 100644 index 00000000..4ebf2007 --- /dev/null +++ b/Ryujinx.Graphics/CdmaProcessor.cs @@ -0,0 +1,99 @@ +using Ryujinx.Graphics.Memory; +using System.Collections.Generic; + +namespace Ryujinx.Graphics +{ + public class CdmaProcessor + { + private const int MethSetMethod = 0x10; + private const int MethSetData = 0x11; + + private NvGpu Gpu; + + public CdmaProcessor(NvGpu Gpu) + { + this.Gpu = Gpu; + } + + public void PushCommands(NvGpuVmm Vmm, int[] CmdBuffer) + { + List Commands = new List(); + + ChClassId CurrentClass = 0; + + for (int Index = 0; Index < CmdBuffer.Length; Index++) + { + int Cmd = CmdBuffer[Index]; + + int Value = (Cmd >> 0) & 0xffff; + int MethodOffset = (Cmd >> 16) & 0xfff; + + ChSubmissionMode SubmissionMode = (ChSubmissionMode)((Cmd >> 28) & 0xf); + + switch (SubmissionMode) + { + case ChSubmissionMode.SetClass: CurrentClass = (ChClassId)(Value >> 6); break; + + case ChSubmissionMode.Incrementing: + { + int Count = Value; + + for (int ArgIdx = 0; ArgIdx < Count; ArgIdx++) + { + int Argument = CmdBuffer[++Index]; + + Commands.Add(new ChCommand(CurrentClass, MethodOffset + ArgIdx, Argument)); + } + + break; + } + + case ChSubmissionMode.NonIncrementing: + { + int Count = Value; + + int[] Arguments = new int[Count]; + + for (int ArgIdx = 0; ArgIdx < Count; ArgIdx++) + { + Arguments[ArgIdx] = CmdBuffer[++Index]; + } + + Commands.Add(new ChCommand(CurrentClass, MethodOffset, Arguments)); + + break; + } + } + } + + ProcessCommands(Vmm, Commands.ToArray()); + } + + private void ProcessCommands(NvGpuVmm Vmm, ChCommand[] Commands) + { + int MethodOffset = 0; + + foreach (ChCommand Command in Commands) + { + switch (Command.MethodOffset) + { + case MethSetMethod: MethodOffset = Command.Arguments[0]; break; + + case MethSetData: + { + if (Command.ClassId == ChClassId.NvDec) + { + Gpu.VideoDecoder.Process(Vmm, MethodOffset, Command.Arguments); + } + else if (Command.ClassId == ChClassId.GraphicsVic) + { + Gpu.VideoImageComposer.Process(Vmm, MethodOffset, Command.Arguments); + } + + break; + } + } + } + } + } +} \ No newline at end of file -- cgit v1.2.3