VideoImageComposer.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. using Ryujinx.Graphics.Memory;
  2. namespace Ryujinx.Graphics.Vic
  3. {
  4. class VideoImageComposer
  5. {
  6. private NvGpu _gpu;
  7. private long _configStructAddress;
  8. private long _outputSurfaceLumaAddress;
  9. private long _outputSurfaceChromaUAddress;
  10. private long _outputSurfaceChromaVAddress;
  11. public VideoImageComposer(NvGpu gpu)
  12. {
  13. _gpu = gpu;
  14. }
  15. public void Process(NvGpuVmm vmm, int methodOffset, int[] arguments)
  16. {
  17. VideoImageComposerMeth method = (VideoImageComposerMeth)methodOffset;
  18. switch (method)
  19. {
  20. case VideoImageComposerMeth.Execute:
  21. Execute(vmm, arguments);
  22. break;
  23. case VideoImageComposerMeth.SetConfigStructOffset:
  24. SetConfigStructOffset(vmm, arguments);
  25. break;
  26. case VideoImageComposerMeth.SetOutputSurfaceLumaOffset:
  27. SetOutputSurfaceLumaOffset(vmm, arguments);
  28. break;
  29. case VideoImageComposerMeth.SetOutputSurfaceChromaUOffset:
  30. SetOutputSurfaceChromaUOffset(vmm, arguments);
  31. break;
  32. case VideoImageComposerMeth.SetOutputSurfaceChromaVOffset:
  33. SetOutputSurfaceChromaVOffset(vmm, arguments);
  34. break;
  35. }
  36. }
  37. private void Execute(NvGpuVmm vmm, int[] arguments)
  38. {
  39. StructUnpacker unpacker = new StructUnpacker(vmm, _configStructAddress + 0x20);
  40. SurfacePixelFormat pixelFormat = (SurfacePixelFormat)unpacker.Read(7);
  41. int chromaLocHoriz = unpacker.Read(2);
  42. int chromaLocVert = unpacker.Read(2);
  43. int blockLinearKind = unpacker.Read(4);
  44. int blockLinearHeightLog2 = unpacker.Read(4);
  45. int reserved0 = unpacker.Read(3);
  46. int reserved1 = unpacker.Read(10);
  47. int surfaceWidthMinus1 = unpacker.Read(14);
  48. int surfaceHeightMinus1 = unpacker.Read(14);
  49. int gobBlockHeight = 1 << blockLinearHeightLog2;
  50. int surfaceWidth = surfaceWidthMinus1 + 1;
  51. int surfaceHeight = surfaceHeightMinus1 + 1;
  52. SurfaceOutputConfig outputConfig = new SurfaceOutputConfig(
  53. pixelFormat,
  54. surfaceWidth,
  55. surfaceHeight,
  56. gobBlockHeight,
  57. _outputSurfaceLumaAddress,
  58. _outputSurfaceChromaUAddress,
  59. _outputSurfaceChromaVAddress);
  60. _gpu.VideoDecoder.CopyPlanes(vmm, outputConfig);
  61. }
  62. private void SetConfigStructOffset(NvGpuVmm vmm, int[] arguments)
  63. {
  64. _configStructAddress = GetAddress(arguments);
  65. }
  66. private void SetOutputSurfaceLumaOffset(NvGpuVmm vmm, int[] arguments)
  67. {
  68. _outputSurfaceLumaAddress = GetAddress(arguments);
  69. }
  70. private void SetOutputSurfaceChromaUOffset(NvGpuVmm vmm, int[] arguments)
  71. {
  72. _outputSurfaceChromaUAddress = GetAddress(arguments);
  73. }
  74. private void SetOutputSurfaceChromaVOffset(NvGpuVmm vmm, int[] arguments)
  75. {
  76. _outputSurfaceChromaVAddress = GetAddress(arguments);
  77. }
  78. private static long GetAddress(int[] arguments)
  79. {
  80. return (long)(uint)arguments[0] << 8;
  81. }
  82. }
  83. }