CdmaProcessor.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using Ryujinx.Graphics.Gpu;
  2. using Ryujinx.Graphics.VDec;
  3. using Ryujinx.Graphics.Vic;
  4. using System.Collections.Generic;
  5. namespace Ryujinx.Graphics
  6. {
  7. public class CdmaProcessor
  8. {
  9. private const int MethSetMethod = 0x10;
  10. private const int MethSetData = 0x11;
  11. private readonly VideoDecoder _videoDecoder;
  12. private readonly VideoImageComposer _videoImageComposer;
  13. public CdmaProcessor()
  14. {
  15. _videoDecoder = new VideoDecoder();
  16. _videoImageComposer = new VideoImageComposer(_videoDecoder);
  17. }
  18. public void PushCommands(GpuContext gpu, int[] cmdBuffer)
  19. {
  20. List<ChCommand> commands = new List<ChCommand>();
  21. ChClassId currentClass = 0;
  22. for (int index = 0; index < cmdBuffer.Length; index++)
  23. {
  24. int cmd = cmdBuffer[index];
  25. int value = (cmd >> 0) & 0xffff;
  26. int methodOffset = (cmd >> 16) & 0xfff;
  27. ChSubmissionMode submissionMode = (ChSubmissionMode)((cmd >> 28) & 0xf);
  28. switch (submissionMode)
  29. {
  30. case ChSubmissionMode.SetClass: currentClass = (ChClassId)(value >> 6); break;
  31. case ChSubmissionMode.Incrementing:
  32. {
  33. int count = value;
  34. for (int argIdx = 0; argIdx < count; argIdx++)
  35. {
  36. int argument = cmdBuffer[++index];
  37. commands.Add(new ChCommand(currentClass, methodOffset + argIdx, argument));
  38. }
  39. break;
  40. }
  41. case ChSubmissionMode.NonIncrementing:
  42. {
  43. int count = value;
  44. int[] arguments = new int[count];
  45. for (int argIdx = 0; argIdx < count; argIdx++)
  46. {
  47. arguments[argIdx] = cmdBuffer[++index];
  48. }
  49. commands.Add(new ChCommand(currentClass, methodOffset, arguments));
  50. break;
  51. }
  52. }
  53. }
  54. ProcessCommands(gpu, commands.ToArray());
  55. }
  56. private void ProcessCommands(GpuContext gpu, ChCommand[] commands)
  57. {
  58. int methodOffset = 0;
  59. foreach (ChCommand command in commands)
  60. {
  61. switch (command.MethodOffset)
  62. {
  63. case MethSetMethod: methodOffset = command.Arguments[0]; break;
  64. case MethSetData:
  65. {
  66. if (command.ClassId == ChClassId.NvDec)
  67. {
  68. _videoDecoder.Process(gpu, methodOffset, command.Arguments);
  69. }
  70. else if (command.ClassId == ChClassId.GraphicsVic)
  71. {
  72. _videoImageComposer.Process(gpu, methodOffset, command.Arguments);
  73. }
  74. break;
  75. }
  76. }
  77. }
  78. }
  79. }
  80. }