aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/CdmaProcessor.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-12-03 00:38:47 -0200
committerGitHub <noreply@github.com>2018-12-03 00:38:47 -0200
commitc86aacde76b5f8e503e2b412385c8491ecc86b3b (patch)
tree8e4737422fba15199c1a6ce7c6345996c0e907b5 /Ryujinx.Graphics/CdmaProcessor.cs
parentad00fd02442cf9c0f00c4562635738042b521efa (diff)
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
Diffstat (limited to 'Ryujinx.Graphics/CdmaProcessor.cs')
-rw-r--r--Ryujinx.Graphics/CdmaProcessor.cs99
1 files changed, 99 insertions, 0 deletions
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<ChCommand> Commands = new List<ChCommand>();
+
+ 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